70 lines
1.7 KiB
TypeScript
70 lines
1.7 KiB
TypeScript
// components/MarkdownEditor.tsx
|
|
import { useEffect, useRef } from 'react';
|
|
import EasyMDE from 'easymde';
|
|
import 'easymde/dist/easymde.min.css';
|
|
|
|
interface MarkdownEditorProps {
|
|
value: string;
|
|
onChange: (value: string) => void;
|
|
}
|
|
|
|
export const MarkdownEditor = ({ value, onChange }: MarkdownEditorProps) => {
|
|
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
|
const editorRef = useRef<EasyMDE | null>(null);
|
|
|
|
// Один раз создаём EasyMDE поверх textarea
|
|
useEffect(() => {
|
|
if (!textareaRef.current) return;
|
|
if (editorRef.current) return; // уже создан
|
|
|
|
const instance = new EasyMDE({
|
|
element: textareaRef.current,
|
|
initialValue: value,
|
|
spellChecker: false,
|
|
minHeight: '200px',
|
|
toolbar: [
|
|
'bold',
|
|
'italic',
|
|
'strikethrough',
|
|
'|',
|
|
'heading',
|
|
'quote',
|
|
'unordered-list',
|
|
'ordered-list',
|
|
'|',
|
|
'link',
|
|
'image',
|
|
'|',
|
|
'preview',
|
|
'side-by-side',
|
|
'fullscreen',
|
|
'|',
|
|
'guide',
|
|
],
|
|
status: false,
|
|
});
|
|
|
|
instance.codemirror.on('change', () => {
|
|
onChange(instance.value());
|
|
});
|
|
|
|
editorRef.current = instance;
|
|
|
|
// При анмаунте красиво убрать за собой
|
|
return () => {
|
|
instance.toTextArea();
|
|
editorRef.current = null;
|
|
};
|
|
}, []);
|
|
|
|
// Если извне поменяли value — обновляем редактор
|
|
useEffect(() => {
|
|
if (editorRef.current && editorRef.current.value() !== value) {
|
|
editorRef.current.value(value);
|
|
}
|
|
}, [value]);
|
|
|
|
// Сам текстариа — просто якорь для EasyMDE
|
|
return <textarea ref={textareaRef} />;
|
|
};
|