Просмотр исходного кода

render CodeMirror with the custom hook

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

+ 15 - 5
apps/app/src/components/PageEditor/PageEditor.tsx

@@ -8,7 +8,7 @@ import nodePath from 'path';
 
 import type { IPageHasId } from '@growi/core';
 import { pathUtils } from '@growi/core/dist/utils';
-import { CodeMirrorEditor } from '@growi/editor';
+import { CodeMirrorEditor, CodeMirrorEditorContainer, useCodeMirrorEditor } from '@growi/editor';
 import detectIndent from 'detect-indent';
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
@@ -80,6 +80,10 @@ export const PageEditor = React.memo((): JSX.Element => {
   const { t } = useTranslation();
   const router = useRouter();
 
+  const editorRef = useRef<IEditorMethods>(null);
+  const previewRef = useRef<HTMLDivElement>(null);
+  const codeMirrorEditorContainerRef = useRef<HTMLDivElement>(null);
+
   const { data: isNotFound } = useIsNotFound();
   const { data: pageId, mutate: mutateCurrentPageId } = useCurrentPageId();
   const { data: currentPagePath } = useCurrentPagePath();
@@ -107,6 +111,15 @@ export const PageEditor = React.memo((): JSX.Element => {
   const { mutate: mutateRemoteRevisionLastUpdatedAt } = useRemoteRevisionLastUpdatedAt();
   const { mutate: mutateRemoteRevisionLastUpdateUser } = useRemoteRevisionLastUpdateUser();
 
+  const { setContainer } = useCodeMirrorEditor({
+    container: codeMirrorEditorContainerRef.current,
+  });
+  useEffect(() => {
+    if (codeMirrorEditorContainerRef.current != null) {
+      setContainer(codeMirrorEditorContainerRef.current);
+    }
+  }, [setContainer]);
+
   const { data: rendererOptions } = usePreviewOptions();
   const { mutate: mutateIsEnabledUnsavedWarning } = useIsEnabledUnsavedWarning();
   const saveOrUpdate = useSaveOrUpdate();
@@ -146,9 +159,6 @@ export const PageEditor = React.memo((): JSX.Element => {
   const { mutate: mutateIsConflict } = useIsConflict();
 
 
-  const editorRef = useRef<IEditorMethods>(null);
-  const previewRef = useRef<HTMLDivElement>(null);
-
   const checkIsConflict = useCallback((data) => {
     const { s2cMessagePageUpdated } = data;
 
@@ -572,7 +582,7 @@ export const PageEditor = React.memo((): JSX.Element => {
           onUpload={uploadHandler}
           onSave={saveWithShortcut}
         /> */}
-        <CodeMirrorEditor />
+        <CodeMirrorEditorContainer ref={codeMirrorEditorContainerRef} />
       </div>
       <div className="d-none d-lg-flex page-editor-preview-container flex-grow-1 flex-basis-0 mw-0">
         <Preview

+ 0 - 20
packages/editor/src/components/CodeMirrorEditor.tsx

@@ -1,20 +0,0 @@
-import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
-import { languages } from '@codemirror/language-data';
-import { scrollPastEnd } from '@codemirror/view';
-import CodeMirror from '@uiw/react-codemirror';
-
-
-import style from './CodeMirrorEditor.module.scss';
-
-
-export const CodeMirrorEditor = (): JSX.Element => {
-  return (
-    <CodeMirror
-      className={`${style['codemirror-editor']}`}
-      extensions={[
-        markdown({ base: markdownLanguage, codeLanguages: languages }),
-        scrollPastEnd(),
-      ]}
-    />
-  );
-};

+ 1 - 1
packages/editor/src/components/CodeMirrorEditor.module.scss → packages/editor/src/components/CodeMirrorEditorContainer.module.scss

@@ -1,4 +1,4 @@
-.codemirror-editor :global {
+.codemirror-editor-container :global {
 
   display: flex;
   align-items: stretch;

+ 9 - 0
packages/editor/src/components/CodeMirrorEditorContainer.tsx

@@ -0,0 +1,9 @@
+import { forwardRef } from 'react';
+
+import style from './CodeMirrorEditorContainer.module.scss';
+
+export const CodeMirrorEditorContainer = forwardRef<HTMLDivElement>((props, ref) => {
+  return (
+    <div {...props} className={`${style['codemirror-editor-container']}`} ref={ref} />
+  );
+});

+ 1 - 1
packages/editor/src/components/index.ts

@@ -1 +1 @@
-export * from './CodeMirrorEditor';
+export * from './CodeMirrorEditorContainer';

+ 1 - 0
packages/editor/src/index.ts

@@ -1 +1,2 @@
 export * from './components';
+export * from './services';

+ 29 - 0
packages/editor/src/services/codemirror-editor.ts

@@ -0,0 +1,29 @@
+import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
+import { languages } from '@codemirror/language-data';
+import { EditorState, Extension } from '@codemirror/state';
+import { EditorView, scrollPastEnd } from '@codemirror/view';
+import { useCodeMirror, type UseCodeMirror } from '@uiw/react-codemirror';
+
+
+export type UseCodeMirrorEditor = UseCodeMirror
+
+type UseCodeMirrorEditorStates = {
+  state: EditorState | undefined;
+  setState: import('react').Dispatch<import('react').SetStateAction<EditorState | undefined>>;
+  view: EditorView | undefined;
+  setView: import('react').Dispatch<import('react').SetStateAction<EditorView | undefined>>;
+  container: HTMLDivElement | undefined;
+  setContainer: import('react').Dispatch<import('react').SetStateAction<HTMLDivElement | undefined>>;
+}
+
+const defaultExtensions: Extension[] = [
+  markdown({ base: markdownLanguage, codeLanguages: languages }),
+  scrollPastEnd(),
+];
+
+export const useCodeMirrorEditor = (props: UseCodeMirrorEditor): UseCodeMirrorEditorStates => {
+  return useCodeMirror({
+    extensions: defaultExtensions,
+    ...props,
+  });
+};

+ 1 - 0
packages/editor/src/services/index.ts

@@ -0,0 +1 @@
+export * from './codemirror-editor';