2
0

CodeMirrorEditorMain.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { useEffect, useMemo } from 'react';
  2. import { type Extension } from '@codemirror/state';
  3. import { keymap, scrollPastEnd } from '@codemirror/view';
  4. import type { IUserHasId } from '@growi/core/dist/interfaces';
  5. import type { ReactCodeMirrorProps } from '@uiw/react-codemirror';
  6. import deepmerge from 'ts-deepmerge';
  7. import { GlobalCodeMirrorEditorKey } from '../../consts';
  8. import { CodeMirrorEditor, type CodeMirrorEditorProps } from '../components-internal/CodeMirrorEditor';
  9. import { setDataLine } from '../services-internal';
  10. import { useCodeMirrorEditorIsolated } from '../stores/codemirror-editor';
  11. import { useCollaborativeEditorMode } from '../stores/use-collaborative-editor-mode';
  12. const additionalExtensions: Extension[] = [
  13. [
  14. scrollPastEnd(),
  15. setDataLine,
  16. ],
  17. ];
  18. type Props = CodeMirrorEditorProps & {
  19. user?: IUserHasId,
  20. pageId?: string,
  21. initialValue?: string,
  22. isEditorMode: boolean,
  23. onEditorsUpdated?: (userList: IUserHasId[]) => void,
  24. }
  25. export const CodeMirrorEditorMain = (props: Props): JSX.Element => {
  26. const {
  27. user, pageId, initialValue, isEditorMode, cmProps,
  28. onSave, onEditorsUpdated, ...otherProps
  29. } = props;
  30. const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(GlobalCodeMirrorEditorKey.MAIN);
  31. useCollaborativeEditorMode(isEditorMode, user, pageId, initialValue, onEditorsUpdated, codeMirrorEditor);
  32. // setup additional extensions
  33. useEffect(() => {
  34. return codeMirrorEditor?.appendExtensions?.(additionalExtensions);
  35. }, [codeMirrorEditor]);
  36. // set handler to save with shortcut key
  37. useEffect(() => {
  38. if (onSave == null) {
  39. return;
  40. }
  41. const extension = keymap.of([
  42. {
  43. key: 'Mod-s',
  44. preventDefault: true,
  45. run: () => {
  46. const doc = codeMirrorEditor?.getDoc();
  47. if (doc != null) {
  48. onSave();
  49. }
  50. return true;
  51. },
  52. },
  53. ]);
  54. const cleanupFunction = codeMirrorEditor?.appendExtensions?.(extension);
  55. return cleanupFunction;
  56. }, [codeMirrorEditor, onSave]);
  57. const cmPropsOverride = useMemo<ReactCodeMirrorProps>(() => deepmerge(
  58. cmProps ?? {},
  59. {
  60. // Disable the basic history configuration since this component uses Y.UndoManager instead
  61. basicSetup: {
  62. history: false,
  63. },
  64. },
  65. ), [cmProps]);
  66. return (
  67. <CodeMirrorEditor
  68. editorKey={GlobalCodeMirrorEditorKey.MAIN}
  69. onSave={onSave}
  70. cmProps={cmPropsOverride}
  71. {...otherProps}
  72. />
  73. );
  74. };