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

Merge branch 'feat/133069-make-button-work-to-create-font-bolt' into feat/133066-able-to-change-text-format-using-button

soumaeda 2 лет назад
Родитель
Сommit
a499cb3d1d

+ 1 - 1
packages/editor/src/components/CodeMirrorEditor/CodeMirrorEditor.tsx

@@ -105,7 +105,7 @@ export const CodeMirrorEditor = (props: Props): JSX.Element => {
   return (
     <div {...getRootProps()} className="flex-expand-vert">
       <CodeMirrorEditorContainer ref={containerRef} />
-      <Toolbar editorKey={editorKey} onFileOpen={open} acceptedFileType={acceptedFileType} />
+      <Toolbar onFileOpen={open} acceptedFileType={acceptedFileType} editorKey={editorKey} />
     </div>
   );
 };

+ 15 - 5
packages/editor/src/components/CodeMirrorEditor/Toolbar/TextFormatTools.tsx

@@ -2,6 +2,8 @@ import { useCallback, useState } from 'react';
 
 import { Collapse } from 'reactstrap';
 
+import type { GlobalCodeMirrorEditorKey } from '../../../consts';
+import { useCodeMirrorEditorIsolated } from '../../../stores';
 
 import styles from './TextFormatTools.module.scss';
 
@@ -30,32 +32,40 @@ const TextFormatToolsToggler = (props: TogglarProps): JSX.Element => {
   );
 };
 
-export const TextFormatTools = (): JSX.Element => {
+type TextFormatToolsType = {
+  editorKey: string | GlobalCodeMirrorEditorKey,
+}
+
+export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
+  const { editorKey } = props;
   const [isOpen, setOpen] = useState(false);
+  const { data: codeMirrorEditor } = useCodeMirrorEditorIsolated(editorKey);
 
   const toggle = useCallback(() => {
     setOpen(bool => !bool);
   }, []);
 
+  const onClickInsertMarkdownElements = (prefix: string, suffix: string) => codeMirrorEditor?.insertMarkdownElements(prefix, suffix);
+
   return (
     <div className="d-flex">
       <TextFormatToolsToggler isOpen={isOpen} onClick={toggle} />
 
       <Collapse isOpen={isOpen} horizontal>
         <div className="d-flex px-1 gap-1" style={{ width: '220px' }}>
-          <button type="button" className="btn btn-toolbar-button">
+          <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertMarkdownElements('**', '**')}>
             <span className="material-symbols-outlined fs-5">format_bold</span>
           </button>
           <button type="button" className="btn btn-toolbar-button">
-            <span className="material-symbols-outlined fs-5">format_italic</span>
+            <span className="material-symbols-outlined fs-5" onClick={() => onClickInsertMarkdownElements('*', '*')}>format_italic</span>
           </button>
-          <button type="button" className="btn btn-toolbar-button">
+          <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertMarkdownElements('~', '~')}>
             <span className="material-symbols-outlined fs-5">format_strikethrough</span>
           </button>
           <button type="button" className="btn btn-toolbar-button">
             <span className="material-symbols-outlined fs-5">block</span>
           </button>
-          <button type="button" className="btn btn-toolbar-button">
+          <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertMarkdownElements('`', '`')}>
             <span className="material-symbols-outlined fs-5">code</span>
           </button>
           <button type="button" className="btn btn-toolbar-button">

+ 4 - 6
packages/editor/src/components/CodeMirrorEditor/Toolbar/Toolbar.tsx

@@ -1,7 +1,5 @@
 import { memo } from 'react';
 
-import { AcceptedUploadFileType } from '../../../consts';
-
 import { AttachmentsDropup } from './AttachmentsDropup';
 import { DiagramButton } from './DiagramButton';
 import { EmojiButton } from './EmojiButton';
@@ -9,23 +7,23 @@ import { TableButton } from './TableButton';
 import { TemplateButton } from './TemplateButton';
 import { TextFormatTools } from './TextFormatTools';
 
+import type { GlobalCodeMirrorEditorKey, AcceptedUploadFileType } from 'src/consts';
 
 import styles from './Toolbar.module.scss';
 
 type Props = {
-  editorKey: string,
+  editorKey: string | GlobalCodeMirrorEditorKey,
   onFileOpen: () => void,
   acceptedFileType: AcceptedUploadFileType
 }
 
 export const Toolbar = memo((props: Props): JSX.Element => {
 
-  const { editorKey, onFileOpen, acceptedFileType } = props;
-
+  const { onFileOpen, acceptedFileType, editorKey } = props;
   return (
     <div className={`d-flex gap-2 p-2 codemirror-editor-toolbar ${styles['codemirror-editor-toolbar']}`}>
       <AttachmentsDropup onFileOpen={onFileOpen} acceptedFileType={acceptedFileType} />
-      <TextFormatTools />
+      <TextFormatTools editorKey={editorKey} />
       <EmojiButton
         editorKey={editorKey}
       />

+ 4 - 0
packages/editor/src/services/codemirror-editor/use-codemirror-editor/use-codemirror-editor.ts

@@ -16,6 +16,7 @@ import { useAppendExtensions, type AppendExtensions } from './utils/append-exten
 import { useFocus, type Focus } from './utils/focus';
 import { useGetDoc, type GetDoc } from './utils/get-doc';
 import { useInitDoc, type InitDoc } from './utils/init-doc';
+import { useInsertMarkdownElements, type InsertMarkdowElements } from './utils/insert-markdown-elements';
 import { useInsertText, type InsertText } from './utils/insert-text';
 import { useReplaceText, type ReplaceText } from './utils/replace-text';
 import { useSetCaretLine, type SetCaretLine } from './utils/set-caret-line';
@@ -37,6 +38,7 @@ type UseCodeMirrorEditorUtils = {
   setCaretLine: SetCaretLine,
   insertText: InsertText,
   replaceText: ReplaceText,
+  insertMarkdownElements: InsertMarkdowElements,
 }
 export type UseCodeMirrorEditor = {
   state: EditorState | undefined;
@@ -89,6 +91,7 @@ export const useCodeMirrorEditor = (props?: UseCodeMirror): UseCodeMirrorEditor
   const setCaretLine = useSetCaretLine(view);
   const insertText = useInsertText(view);
   const replaceText = useReplaceText(view);
+  const insertMarkdownElements = useInsertMarkdownElements(view);
 
   return {
     state,
@@ -100,5 +103,6 @@ export const useCodeMirrorEditor = (props?: UseCodeMirror): UseCodeMirrorEditor
     setCaretLine,
     insertText,
     replaceText,
+    insertMarkdownElements,
   };
 };

+ 27 - 0
packages/editor/src/services/codemirror-editor/use-codemirror-editor/utils/insert-markdown-elements.ts

@@ -0,0 +1,27 @@
+import { useCallback } from 'react';
+
+import { EditorView } from '@codemirror/view';
+
+export type InsertMarkdowElements = (
+  prefix: string,
+  suffix: string,
+) => void;
+
+export const useInsertMarkdownElements = (view?: EditorView): InsertMarkdowElements => {
+
+  return useCallback((prefix, suffix) => {
+    const selection = view?.state.sliceDoc(
+      view?.state.selection.main.from,
+      view?.state.selection.main.to,
+    );
+    const cursorPos = view?.state.selection.main.head;
+    const insertText = view?.state.replaceSelection(prefix + selection + suffix);
+
+    if (insertText == null || cursorPos == null) {
+      return;
+    }
+    view?.dispatch(insertText);
+    view?.dispatch({ selection: { anchor: cursorPos + prefix.length } });
+    view?.focus();
+  }, [view]);
+};