CodeMirrorEditor.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import {
  2. forwardRef, useEffect, useMemo, useRef,
  3. } from 'react';
  4. import { keymap } from '@codemirror/view';
  5. import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
  6. import { GlobalCodeMirrorEditorKey } from '../consts';
  7. import { useCodeMirrorEditorIsolated } from '../stores';
  8. import style from './CodeMirrorEditor.module.scss';
  9. const CodeMirrorEditorContainer = forwardRef<HTMLDivElement>((props, ref) => {
  10. return (
  11. <div {...props} className={`${style['codemirror-editor-container']}`} ref={ref} />
  12. );
  13. });
  14. type Props = {
  15. onChange?: (value: string) => void,
  16. onSave?: () => void,
  17. }
  18. export const CodeMirrorEditor = (props: Props): JSX.Element => {
  19. const {
  20. onSave, onChange,
  21. } = props;
  22. const containerRef = useRef(null);
  23. const cmProps = useMemo<ReactCodeMirrorProps>(() => {
  24. return {
  25. doc: '',
  26. onChange,
  27. };
  28. }, [onChange]);
  29. const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN, containerRef.current, cmProps);
  30. // set handler to save with shortcut key
  31. useEffect(() => {
  32. if (onSave == null) {
  33. return;
  34. }
  35. const extension = keymap.of([
  36. {
  37. key: 'Mod-s',
  38. preventDefault: true,
  39. run: () => {
  40. const doc = codeMirrorEditor?.getDoc();
  41. if (doc != null) {
  42. onSave();
  43. }
  44. return true;
  45. },
  46. },
  47. ]);
  48. const cleanupFunction = codeMirrorEditor?.appendExtension?.(extension);
  49. return cleanupFunction;
  50. }, [codeMirrorEditor, onSave]);
  51. return <CodeMirrorEditorContainer ref={containerRef} />;
  52. };