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

+ 4 - 10
packages/editor/src/components/playground/Playground.tsx

@@ -1,7 +1,7 @@
-import { useEffect, useRef } from 'react';
+import { useRef } from 'react';
 
 import { CodeMirrorEditorContainer } from '..';
-import { useCodeMirrorEditor } from '../../services';
+import { useCodeMirrorEditorMain } from '../../stores';
 
 import { PlaygroundController } from './PlaygroundController';
 
@@ -9,16 +9,10 @@ export const Playground = (): JSX.Element => {
 
   const containerRef = useRef(null);
 
-  const { setContainer } = useCodeMirrorEditor({
+  useCodeMirrorEditorMain({
     container: containerRef.current,
   });
 
-  useEffect(() => {
-    if (containerRef.current != null) {
-      setContainer(containerRef.current);
-    }
-  }, [setContainer]);
-
   return (
     <>
       <div className="flex-grow-1 d-flex flex-column justify-content-center align-items-center bg-dark" style={{ minHeight: '83px' }}>
@@ -28,7 +22,7 @@ export const Playground = (): JSX.Element => {
         <div className="flex-grow-1 d-flex flex-column" style={{ flexBasis: 0 }}>
           <CodeMirrorEditorContainer ref={containerRef} />
         </div>
-        <div className="flex-grow-1 d-flex flex-column bg-light border-start border-dark-subtle p-3" style={{ flexBasis: 0 }}>
+        <div className="flex-grow-1 mw-0 d-flex flex-column bg-light border-start border-dark-subtle p-3" style={{ flexBasis: 0 }}>
           <PlaygroundController />
         </div>
       </div>

+ 16 - 1
packages/editor/src/components/playground/PlaygroundController.tsx

@@ -1,10 +1,25 @@
 import { useCallback } from 'react';
 
+import { useCodeMirrorEditorMain } from '../../stores';
+
 export const PlaygroundController = (): JSX.Element => {
 
+  const { data: states } = useCodeMirrorEditorMain();
+
   const initEditorValue = useCallback(() => {
+    if (states == null) {
+      return;
+    }
+
+    states.view?.dispatch({
+      changes: {
+        from: 0,
+        to: states.state?.doc.toString().length,
+        insert: '# Header\n\n- foo\n-bar\n',
+      },
+    });
 
-  }, []);
+  }, [states]);
 
   return (
     <>

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

@@ -1,3 +1,5 @@
+import { useEffect } from 'react';
+
 import { markdown, markdownLanguage } from '@codemirror/lang-markdown';
 import { languages } from '@codemirror/language-data';
 import { EditorState, Extension } from '@codemirror/state';
@@ -5,9 +7,9 @@ import { EditorView, scrollPastEnd } from '@codemirror/view';
 import { useCodeMirror, type UseCodeMirror } from '@uiw/react-codemirror';
 
 
-export type UseCodeMirrorEditor = UseCodeMirror
+export type UseCodeMirrorEditor = UseCodeMirror;
 
-type UseCodeMirrorEditorStates = {
+export type UseCodeMirrorEditorStates = {
   state: EditorState | undefined;
   setState: import('react').Dispatch<import('react').SetStateAction<EditorState | undefined>>;
   view: EditorView | undefined;
@@ -21,9 +23,20 @@ const defaultExtensions: Extension[] = [
   scrollPastEnd(),
 ];
 
-export const useCodeMirrorEditor = (props: UseCodeMirrorEditor): UseCodeMirrorEditorStates => {
-  return useCodeMirror({
+export const useCodeMirrorEditor = (props?: UseCodeMirrorEditor): UseCodeMirrorEditorStates => {
+
+  const codemirror = useCodeMirror({
     extensions: defaultExtensions,
     ...props,
   });
+
+  const { setContainer } = codemirror;
+
+  useEffect(() => {
+    if (props?.container != null) {
+      setContainer(props.container);
+    }
+  }, [props?.container, setContainer]);
+
+  return codemirror;
 };

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

@@ -0,0 +1,12 @@
+import type { SWRResponse } from 'swr';
+
+
+import type { UseCodeMirrorEditor, UseCodeMirrorEditorStates } from '../services';
+import { useCodeMirrorEditor } from '../services';
+
+import { useStaticSWR } from './use-static-swr';
+
+export const useCodeMirrorEditorMain = (props?: UseCodeMirrorEditor): SWRResponse<UseCodeMirrorEditorStates> => {
+  const states = useCodeMirrorEditor(props);
+  return useStaticSWR('codeMirrorEditorMain', props != null ? states : undefined);
+};

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

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

+ 33 - 0
packages/editor/src/stores/use-static-swr.tsx

@@ -0,0 +1,33 @@
+import {
+  Key, SWRConfiguration, SWRResponse, useSWRConfig,
+} from 'swr';
+import useSWRImmutable from 'swr/immutable';
+
+
+export function useStaticSWR<Data, Error>(key: Key): SWRResponse<Data, Error>;
+export function useStaticSWR<Data, Error>(key: Key, data: Data | undefined): SWRResponse<Data, Error>;
+export function useStaticSWR<Data, Error>(key: Key, data: Data | undefined,
+  configuration: SWRConfiguration<Data, Error> | undefined): SWRResponse<Data, Error>;
+
+export function useStaticSWR<Data, Error>(
+    ...args: readonly [Key]
+    | readonly [Key, Data | undefined]
+    | readonly [Key, Data | undefined, SWRConfiguration<Data, Error> | undefined]
+): SWRResponse<Data, Error> {
+  const [key, data, configuration] = args;
+
+  // assert.notStrictEqual(configuration?.fetcher, null, 'useStaticSWR does not support \'configuration.fetcher\'');
+
+  const { cache } = useSWRConfig();
+  const swrResponse = useSWRImmutable(key, null, {
+    ...configuration,
+    fallbackData: configuration?.fallbackData ?? cache.get(key)?.data,
+  });
+
+  // write data to cache directly
+  if (data !== undefined) {
+    cache.set(key, { ...cache.get(key), data });
+  }
+
+  return swrResponse;
+}