import { BlockTypeSelect, BoldItalicUnderlineToggles, codeBlockPlugin, CodeToggle, CreateLink, diffSourcePlugin, DiffSourceToggleWrapper, directivesPlugin, headingsPlugin, imagePlugin, InsertCodeBlock, InsertImage, InsertTable, InsertThematicBreak, linkDialogPlugin, linkPlugin, listsPlugin, ListsToggle, markdownShortcutPlugin, MDXEditor, MDXEditorMethods, MDXEditorProps, quotePlugin, Separator, StrikeThroughSupSubToggles, tablePlugin, thematicBreakPlugin, toolbarPlugin, UndoRedo } from '@mdxeditor/editor' import { PlainTextCodeEditorDescriptor } from './PlainTextCodeEditorDescriptor' import { YoutubeDirectiveDescriptor } from './YoutubeDirectiveDescriptor' import { YouTubeButton } from './YoutubeButton' import '@mdxeditor/editor/style.css' import '../../styles/mdxEditor.scss' import React, { forwardRef, useCallback, useImperativeHandle, useMemo, useRef } from 'react' import { ImageDialog } from './ImageDialog' import { LinkDialog } from './LinkDialog' export interface EditorRef { setMarkdown: (md: string) => void } interface EditorProps extends MDXEditorProps {} /** * The editor component is small wrapper (`forwardRef`) around {@link MDXEditor MDXEditor} that sets up the toolbars and plugins, and requires `markdown` and `onChange`. * To reset editor markdown it's required to pass the {@link EditorRef EditorRef}. * * Extends {@link MDXEditorProps MDXEditorProps} * * **Important**: the markdown is not a state, but an _initialState_ and is not "controlled". * All updates are handled with onChange and will not be reflected on markdown prop. * This component should never re-render if used correctly. * @see https://mdxeditor.dev/editor/docs/getting-started#basic-usage */ export const Editor = React.memo( forwardRef(({ markdown, onChange, ...rest }, ref) => { const editorRef = useRef(null) const setMarkdown = useCallback((md: string) => { editorRef.current?.setMarkdown(md) }, []) useImperativeHandle(ref, () => ({ setMarkdown })) const plugins = useMemo( () => [ toolbarPlugin({ toolbarContents: () => ( } /> ) }), headingsPlugin(), diffSourcePlugin({ viewMode: 'rich-text', diffMarkdown: markdown }), quotePlugin(), imagePlugin({ ImageDialog: ImageDialog }), tablePlugin(), linkPlugin(), linkDialogPlugin({ LinkDialog: LinkDialog }), listsPlugin(), thematicBreakPlugin(), directivesPlugin({ directiveDescriptors: [YoutubeDirectiveDescriptor] }), markdownShortcutPlugin(), // HACK: due to a bug with shortcut interaction shortcut for code block is disabled // Editor freezes if you type in ```word and put a space in between ``` word codeBlockPlugin({ defaultCodeBlockLanguage: '', codeBlockEditorDescriptors: [PlainTextCodeEditorDescriptor] }) ], // eslint-disable-next-line react-hooks/exhaustive-deps [] ) return ( ) }), () => true )