Yuki Takei 2 лет назад
Родитель
Сommit
a365d1efe0

+ 3 - 30
packages/editor/src/components/CodeMirrorEditor.tsx

@@ -1,8 +1,7 @@
 import {
-  forwardRef, useEffect, useMemo, useRef,
+  forwardRef, useMemo, useRef,
 } from 'react';
 
-import { keymap } from '@codemirror/view';
 import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
 
 import { GlobalCodeMirrorEditorKey } from '../consts';
@@ -20,13 +19,12 @@ const CodeMirrorEditorContainer = forwardRef<HTMLDivElement>((props, ref) => {
 type Props = {
   editorKey: string | GlobalCodeMirrorEditorKey,
   onChange?: (value: string) => void,
-  onSave?: () => void,
 }
 
 export const CodeMirrorEditor = (props: Props): JSX.Element => {
   const {
     editorKey,
-    onSave, onChange,
+    onChange,
   } = props;
 
   const containerRef = useRef(null);
@@ -36,32 +34,7 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
       onChange,
     };
   }, [onChange]);
-  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey, containerRef.current, cmProps);
-
-  // set handler to save with shortcut key
-  useEffect(() => {
-    if (onSave == null) {
-      return;
-    }
-
-    const extension = keymap.of([
-      {
-        key: 'Mod-s',
-        preventDefault: true,
-        run: () => {
-          const doc = codeMirrorEditor?.getDoc();
-          if (doc != null) {
-            onSave();
-          }
-          return true;
-        },
-      },
-    ]);
-
-    const cleanupFunction = codeMirrorEditor?.appendExtension?.(extension);
-
-    return cleanupFunction;
-  }, [codeMirrorEditor, onSave]);
+  useCodeMirrorEditorIsolated(editorKey, containerRef.current, cmProps);
 
   return <CodeMirrorEditorContainer ref={containerRef} />;
 };

+ 65 - 0
packages/editor/src/components/CodeMirrorEditorMain.tsx

@@ -0,0 +1,65 @@
+import { useEffect } from 'react';
+
+import type { Extension } from '@codemirror/state';
+import { keymap, scrollPastEnd } from '@codemirror/view';
+
+import { GlobalCodeMirrorEditorKey } from '../consts';
+import { useCodeMirrorEditorIsolated } from '../stores';
+
+import { CodeMirrorEditor } from '.';
+
+
+const defaultExtensions: Extension[] = [
+  scrollPastEnd(),
+];
+
+
+type Props = {
+  onChange?: (value: string) => void,
+  onSave?: () => void,
+}
+
+export const CodeMirrorEditorMain = (props: Props): JSX.Element => {
+  const {
+    onSave, onChange,
+  } = props;
+
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
+
+  // set handler to save with shortcut key
+  useEffect(() => {
+    return codeMirrorEditor?.appendExtensions?.(defaultExtensions);
+  }, [codeMirrorEditor]);
+
+  // set handler to save with shortcut key
+  useEffect(() => {
+    if (onSave == null) {
+      return;
+    }
+
+    const extension = keymap.of([
+      {
+        key: 'Mod-s',
+        preventDefault: true,
+        run: () => {
+          const doc = codeMirrorEditor?.getDoc();
+          if (doc != null) {
+            onSave();
+          }
+          return true;
+        },
+      },
+    ]);
+
+    const cleanupFunction = codeMirrorEditor?.appendExtensions?.(extension);
+
+    return cleanupFunction;
+  }, [codeMirrorEditor, onSave]);
+
+  return (
+    <CodeMirrorEditor
+      editorKey={GlobalCodeMirrorEditorKey.MAIN}
+      onChange={onChange}
+    />
+  );
+};

+ 2 - 3
packages/editor/src/components/playground/Playground.tsx

@@ -4,9 +4,9 @@ import {
 
 import { toast } from 'react-toastify';
 
-import { CodeMirrorEditor } from '..';
 import { GlobalCodeMirrorEditorKey } from '../../consts';
 import { useCodeMirrorEditorIsolated } from '../../stores';
+import { CodeMirrorEditorMain } from '../CodeMirrorEditorMain';
 
 import { PlaygroundController } from './PlaygroundController';
 import { Preview } from './Preview';
@@ -44,8 +44,7 @@ export const Playground = (): JSX.Element => {
       </div>
       <div className="flex-expand-horiz">
         <div className="flex-expand-vert">
-          <CodeMirrorEditor
-            editorKey={GlobalCodeMirrorEditorKey.MAIN}
+          <CodeMirrorEditorMain
             onSave={saveHandler}
             onChange={setMarkdownToPreview}
           />

+ 4 - 4
packages/editor/src/services/codemirror-editor/use-codemirror-editor/use-codemirror-editor.ts

@@ -7,7 +7,7 @@ import { EditorView } from '@codemirror/view';
 import { useCodeMirror, type UseCodeMirror } from '@uiw/react-codemirror';
 import deepmerge from 'ts-deepmerge';
 
-import { AppendExtension, useAppendExtension } from './utils/append-extension';
+import { useAppendExtensions, type AppendExtensions } from './utils/append-extension';
 import { useFocus, type Focus } from './utils/focus';
 import { useGetDoc, type GetDoc } from './utils/get-doc';
 import { useInitDoc, type InitDoc } from './utils/init-doc';
@@ -15,7 +15,7 @@ import { useSetCaretLine, type SetCaretLine } from './utils/set-caret-line';
 
 type UseCodeMirrorEditorUtils = {
   initDoc: InitDoc,
-  appendExtension: AppendExtension,
+  appendExtensions: AppendExtensions,
   getDoc: GetDoc,
   focus: Focus,
   setCaretLine: SetCaretLine,
@@ -42,7 +42,7 @@ export const useCodeMirrorEditor = (props?: UseCodeMirror): UseCodeMirrorEditor
   const { state, view } = useCodeMirror(mergedProps);
 
   const initDoc = useInitDoc(view);
-  const appendExtension = useAppendExtension(view);
+  const appendExtensions = useAppendExtensions(view);
   const getDoc = useGetDoc(view);
   const focus = useFocus(view);
   const setCaretLine = useSetCaretLine(view);
@@ -56,7 +56,7 @@ export const useCodeMirrorEditor = (props?: UseCodeMirror): UseCodeMirrorEditor
     state,
     view,
     initDoc,
-    appendExtension,
+    appendExtensions,
     getDoc,
     focus,
     setCaretLine,

+ 13 - 7
packages/editor/src/services/codemirror-editor/use-codemirror-editor/utils/append-extension.ts

@@ -3,17 +3,23 @@ import { useCallback } from 'react';
 import { Compartment, Extension, StateEffect } from '@codemirror/state';
 import { EditorView } from '@codemirror/view';
 
-type CleanupFunction = () => void;
-export type AppendExtension = (extension: Extension) => CleanupFunction | undefined;
+type CleanupFunctions = () => void;
+export type AppendExtensions = (extensions: Extension | Extension[]) => CleanupFunctions | undefined;
 
-export const useAppendExtension = (view?: EditorView): AppendExtension => {
+export const useAppendExtensions = (view?: EditorView): AppendExtensions => {
+
+  return useCallback((args) => {
+    const extensions = Array.isArray(args)
+      ? args
+      : [args];
 
-  return useCallback((extension) => {
     const compartment = new Compartment();
     view?.dispatch({
-      effects: StateEffect.appendConfig.of(
-        compartment.of(extension),
-      ),
+      effects: extensions.map((extension) => {
+        return StateEffect.appendConfig.of(
+          compartment.of(extension),
+        );
+      }),
     });
 
     // return cleanup function

+ 0 - 7
packages/editor/src/stores/codemirror-editor.ts

@@ -1,7 +1,5 @@
 import { useMemo, useRef } from 'react';
 
-import { type Extension } from '@codemirror/state';
-import { scrollPastEnd } from '@codemirror/view';
 import { useSWRStatic } from '@growi/core/dist/swr';
 import type { ReactCodeMirrorProps, UseCodeMirror } from '@uiw/react-codemirror';
 import type { SWRResponse } from 'swr';
@@ -21,10 +19,6 @@ const isDeepEquals = <T extends object>(obj1: T, obj2: T): boolean => {
 };
 
 
-const defaultExtensionsMain: Extension[] = [
-  scrollPastEnd(),
-];
-
 export const useCodeMirrorEditorIsolated = (
     key: string | null, container?: HTMLDivElement | null, props?: ReactCodeMirrorProps,
 ): SWRResponse<UseCodeMirrorEditor> => {
@@ -38,7 +32,6 @@ export const useCodeMirrorEditorIsolated = (
       props ?? {},
       {
         container,
-        extensions: defaultExtensionsMain,
       },
     );
   }, [container, props]);