Browse Source

impl initState on UseCodeMirrorEditor

Yuki Takei 2 years ago
parent
commit
b3c66dfb94

+ 4 - 5
packages/editor/src/components/playground/PlaygroundController.tsx

@@ -4,13 +4,12 @@ import { useCodeMirrorEditorMain } from '../../stores';
 
 export const PlaygroundController = (): JSX.Element => {
 
-  const { initDoc } = useCodeMirrorEditorMain();
+  const { data } = useCodeMirrorEditorMain();
 
+  const initState = data?.initState;
   const initEditorValue = useCallback(() => {
-
-    initDoc('# Header\n\n- foo\n-bar\n');
-
-  }, [initDoc]);
+    initState?.({ doc: '# Header\n\n- foo\n-bar\n' });
+  }, [initState]);
 
   return (
     <>

+ 11 - 0
packages/editor/src/services/codemirror-editor/interfaces/react-codemirror.ts

@@ -0,0 +1,11 @@
+import type { EditorState } from '@codemirror/state';
+import type { EditorView } from '@codemirror/view';
+
+export 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>>;
+}

+ 32 - 15
packages/editor/src/services/codemirror-editor/use-codemirror-editor.ts

@@ -1,40 +1,54 @@
-import { useEffect } from 'react';
+import { useCallback, useEffect } from 'react';
 
 import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
 import { languages } from '@codemirror/language-data';
-import type { EditorState, Extension } from '@codemirror/state';
-import type { EditorView } from '@codemirror/view';
+import { EditorState, type EditorStateConfig, type Extension } from '@codemirror/state';
 import { basicSetup, useCodeMirror, type UseCodeMirror } from '@uiw/react-codemirror';
 
+import { UseCodeMirrorEditorStates } from './interfaces/react-codemirror';
 
 export type UseCodeMirrorEditor = UseCodeMirror;
 
-export 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>>;
+type UseCodeMirrorEditorUtils = {
+  initState: (config?: EditorStateConfig) => void,
 }
 
-export const defaultExtensions: Extension[] = [
+export type UseCodeMirrorEditorResponse = UseCodeMirrorEditorStates & UseCodeMirrorEditorUtils;
+
+const defaultExtensions: Extension[] = [
   markdown({ base: markdownLanguage, codeLanguages: languages }),
 ];
 
-export const defaultExtensionsToInit: Extension[] = [
+const defaultExtensionsToInit: Extension[] = [
   ...basicSetup(),
   ...defaultExtensions,
 ];
 
-export const useCodeMirrorEditor = (props?: UseCodeMirrorEditor): UseCodeMirrorEditorStates => {
+export const useCodeMirrorEditor = (props?: UseCodeMirrorEditor): UseCodeMirrorEditorResponse => {
 
   const codemirror = useCodeMirror({
     extensions: defaultExtensions,
     ...props,
   });
 
-  const { setContainer } = codemirror;
+  const { view, setContainer } = codemirror;
+
+  // implement initState method
+  const initState = useCallback((config?: EditorStateConfig): void => {
+    if (view == null) {
+      return;
+    }
+
+    const newState = EditorState.create({
+      ...config,
+      extensions: [
+        ...defaultExtensionsToInit,
+        ...(props?.extensions ?? []),
+      ],
+    });
+
+    view.setState(newState);
+  }, [props?.extensions, view]);
 
   useEffect(() => {
     if (props?.container != null) {
@@ -42,5 +56,8 @@ export const useCodeMirrorEditor = (props?: UseCodeMirrorEditor): UseCodeMirrorE
     }
   }, [props?.container, setContainer]);
 
-  return codemirror;
+  return {
+    ...codemirror,
+    initState,
+  };
 };

+ 8 - 26
packages/editor/src/stores/codemirror-editor.ts

@@ -1,13 +1,13 @@
 import { useMemo } from 'react';
 
-import { EditorState, type Extension } from '@codemirror/state';
+import { type Extension } from '@codemirror/state';
 import { scrollPastEnd } from '@codemirror/view';
 import {
   type SWRResponseWithUtils, withUtils,
 } from '@growi/core/dist/swr';
 
-import type { UseCodeMirrorEditor, UseCodeMirrorEditorStates } from '../services';
-import { defaultExtensionsToInit, useCodeMirrorEditor } from '../services';
+import type { UseCodeMirrorEditor, UseCodeMirrorEditorResponse } from '../services';
+import { useCodeMirrorEditor } from '../services';
 
 import { useStaticSWR } from './use-static-swr';
 
@@ -15,16 +15,11 @@ const defaultExtensionsMain: Extension[] = [
   scrollPastEnd(),
 ];
 
-const defaultExtensionsToInitMain: Extension[] = [
-  ...defaultExtensionsToInit,
-  ...defaultExtensionsMain,
-];
-
-type OperationUtils = {
-  initDoc: (doc?: string) => void,
-}
+type MainEditorUtils = {
+  // impl something
+};
 
-export const useCodeMirrorEditorMain = (container?: HTMLDivElement | null): SWRResponseWithUtils<OperationUtils, UseCodeMirrorEditorStates> => {
+export const useCodeMirrorEditorMain = (container?: HTMLDivElement | null): SWRResponseWithUtils<MainEditorUtils, UseCodeMirrorEditorResponse> => {
   const props = useMemo<UseCodeMirrorEditor>(() => {
     return {
       container,
@@ -38,19 +33,6 @@ export const useCodeMirrorEditorMain = (container?: HTMLDivElement | null): SWRR
   const swrResponse = useStaticSWR('codeMirrorEditorMain', container != null ? states : undefined);
 
   return withUtils(swrResponse, {
-    initDoc: (doc) => {
-      const currentView = swrResponse.data?.view;
-      if (currentView == null) {
-        return;
-      }
-
-      // create a new state
-      const newState = EditorState.create({
-        doc,
-        extensions: defaultExtensionsToInitMain,
-      });
-
-      currentView.setState(newState);
-    },
+    // impl something
   });
 };