Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | import 'quill/dist/quill.snow.css';
import 'quill/dist/quill.bubble.css';
import { useQuill } from 'react-quilljs';
import React from 'react';
import { DeltaStatic } from 'quill';
import dynamic from 'next/dynamic';
import { usePostImageUploadMutation } from '@lib/api/mutations';
interface QuillEditorProps {
value?: DeltaStatic;
onChange: (delta?: DeltaStatic) => unknown;
disabled?: boolean;
}
const modules = {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
[{ header: [1, 2, 3, false] }],
[{ align: '' }, { align: 'center' }, { align: 'right' }, { align: 'justify' }],
[{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
['link', 'image'],
['clean']
]
};
function QuillEditor({ value, onChange, disabled }: QuillEditorProps) {
const { quill, quillRef } = useQuill({ modules });
const { mutateAsync } = usePostImageUploadMutation();
React.useEffect(() => {
if (!quill) return;
if (value) {
// Hack: setContents 의 인자에 delta operation 을 넣을 수 있습니다.
// 참조: https://quilljs.com/docs/api/#setcontents
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
quill.setContents(value);
}
const insertToEditor = (url: string) => {
const range = quill.getSelection();
quill.insertEmbed(range?.index || 0, 'image', url);
};
const saveToServer = async (file: File) => {
const res = await mutateAsync({ file });
if (!res.data.url) return;
insertToEditor(res.data.url);
};
const selectLocalImage = () => {
const input = document.createElement('input');
input.setAttribute('type', 'file');
input.setAttribute('accept', 'image/*');
input.click();
input.onchange = () => {
const file = input.files?.[0];
saveToServer(file as File);
};
};
function textChange() {
if (!quill) return;
const delta = quill.getContents();
if (!delta || (delta.ops?.[0].insert === '\n' && quill.getLength() < 2)) {
onChange(undefined);
} else {
onChange(delta);
}
}
quill.on('text-change', textChange);
quill.getModule('toolbar').addHandler('image', selectLocalImage);
if (disabled) {
quill.disable();
}
// eslint-disable-next-line consistent-return
return () => {
quill.off('text-change', textChange);
};
}, [quill]);
return <div ref={quillRef} />;
}
export default dynamic(async () => QuillEditor, { ssr: false });
|