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

make UncontrolledCodeMirror FC

Yuki Takei 3 лет назад
Родитель
Сommit
a9d5572f66
1 измененных файлов с 53 добавлено и 54 удалено
  1. 53 54
      packages/app/src/components/UncontrolledCodeMirror.tsx

+ 53 - 54
packages/app/src/components/UncontrolledCodeMirror.tsx

@@ -1,81 +1,80 @@
 import React, {
-  forwardRef, ReactNode, Ref,
+  useCallback, useRef, MutableRefObject,
 } from 'react';
 
 import { Editor } from 'codemirror';
 import { ICodeMirror, UnControlled as CodeMirror } from 'react-codemirror2';
 
-import AbstractEditor, { AbstractEditorProps } from '~/components/PageEditor/AbstractEditor';
-
 window.CodeMirror = require('codemirror');
 require('codemirror/addon/display/placeholder');
 require('~/client/util/codemirror/gfm-growi.mode');
 
-export interface UncontrolledCodeMirrorProps extends AbstractEditorProps {
+export interface UncontrolledCodeMirrorProps extends ICodeMirror {
   value: string;
-  options?: ICodeMirror['options'];
   isGfmMode?: boolean;
   lineNumbers?: boolean;
+  onScrollCursorIntoView?: (line: number) => void;
+  onSave?: () => Promise<void>;
+  onPasteFiles?: (event: Event) => void;
+  onCtrlEnter?: (event: Event) => void;
 }
 
-interface UncontrolledCodeMirrorCoreProps extends UncontrolledCodeMirrorProps {
-  forwardedRef: Ref<UncontrolledCodeMirrorCore>;
-}
-
-export class UncontrolledCodeMirrorCore extends AbstractEditor<UncontrolledCodeMirrorCoreProps> {
+export const UncontrolledCodeMirror = React.forwardRef<CodeMirror|null, UncontrolledCodeMirrorProps>((props, forwardedRef): JSX.Element => {
 
-  editor: Editor;
+  const wrapperRef = useRef<CodeMirror|null>();
 
-  // wrapperRef: RefObject<any>;
+  const editorRef = useRef<Editor>();
 
-  constructor(props: UncontrolledCodeMirrorCoreProps) {
-    super(props);
-    this.editorDidMount = this.editorDidMount.bind(this);
-    this.editorWillUnmount = this.editorWillUnmount.bind(this);
-  }
+  const editorDidMountHandler = useCallback((editor: Editor): void => {
+    editorRef.current = editor;
+  }, []);
 
-  editorDidMount(e: Editor): void {
-    this.editor = e;
-  }
-
-  editorWillUnmount(): void {
+  const editorWillUnmountHandler = useCallback((): void => {
     // workaround to fix editor duplicating by https://github.com/scniro/react-codemirror2/issues/284#issuecomment-1155928554
-    (this.editor as any).display.wrapper.remove();
-  }
-
-  override render(): ReactNode {
+    if (editorRef.current != null) {
+      (editorRef.current as any).display.wrapper.remove();
+    }
+    if (wrapperRef.current != null) {
+      (wrapperRef.current as any).hydrated = false;
+    }
+  }, []);
+
+  const {
+    value, lineNumbers, options,
+    ...rest
+  } = props;
+
+  // default true
+  const isGfmMode = rest.isGfmMode ?? true;
 
-    const {
-      value, isGfmMode, lineNumbers, options, forwardedRef,
-      ...rest
-    } = this.props;
-
-    return (
-      <CodeMirror
-        ref={forwardedRef}
-        value={value}
-        options={{
-          lineNumbers: lineNumbers ?? true,
-          mode: isGfmMode ? 'gfm-growi' : undefined,
-          tabSize: 4,
-          ...options,
-        }}
-        editorDidMount={this.editorDidMount}
-        editorWillUnmount={this.editorWillUnmount}
-        {...rest}
-      />
-    );
-  }
-
-}
-
-export const UncontrolledCodeMirror = forwardRef<UncontrolledCodeMirrorCore, UncontrolledCodeMirrorProps>((props, ref) => {
   return (
-    <UncontrolledCodeMirrorCore
-      {...props}
-      forwardedRef={ref}
+    <CodeMirror
+      ref={(elem) => {
+        // register to wrapperRef
+        wrapperRef.current = elem;
+        // register to forwardedRef
+        if (forwardedRef != null) {
+          if (typeof forwardedRef === 'function') {
+            forwardedRef(elem);
+          }
+          else {
+            (forwardedRef as MutableRefObject<CodeMirror|null>).current = elem;
+          }
+        }
+      }}
+      value={value}
+      options={{
+        lineNumbers: lineNumbers ?? true,
+        mode: isGfmMode ? 'gfm-growi' : undefined,
+        tabSize: 4,
+        ...options,
+      }}
+      editorDidMount={editorDidMountHandler}
+      editorWillUnmount={editorWillUnmountHandler}
+      {...rest}
     />
   );
+
 });
 
 UncontrolledCodeMirror.displayName = 'UncontrolledCodeMirror';