Przeglądaj źródła

Merge pull request #5748 from weseek/feat/gw7782-use-modal-to-emojiPicker

feat: gw7782 use modal to emoji picker
cao 4 lat temu
rodzic
commit
b7361b5b90

+ 23 - 23
packages/app/src/components/PageEditor/CodeMirrorEditor.jsx

@@ -1,37 +1,37 @@
 import React from 'react';
-import PropTypes from 'prop-types';
 
-import urljoin from 'url-join';
+import { createValidator } from '@growi/codemirror-textlint';
 import * as codemirror from 'codemirror';
-import { Button } from 'reactstrap';
-
 import { JSHINT } from 'jshint';
-
-import * as loadScript from 'simple-load-script';
 import * as loadCssSync from 'load-css-file';
+import PropTypes from 'prop-types';
+import { Button } from 'reactstrap';
+import * as loadScript from 'simple-load-script';
+import urljoin from 'url-join';
 
-import { createValidator } from '@growi/codemirror-textlint';
-import EmojiPicker from './EmojiPicker';
-import EmojiPickerHelper from './EmojiPickerHelper';
 import InterceptorManager from '~/services/interceptor-manager';
 import loggerFactory from '~/utils/logger';
 
-import AbstractEditor from './AbstractEditor';
-import SimpleCheatsheet from './SimpleCheatsheet';
+import { UncontrolledCodeMirror } from '../UncontrolledCodeMirror';
 
-import pasteHelper from './PasteHelper';
-import PreventMarkdownListInterceptor from './PreventMarkdownListInterceptor';
-import MarkdownTableInterceptor from './MarkdownTableInterceptor';
-import mlu from './MarkdownLinkUtil';
-import mtu from './MarkdownTableUtil';
-import mdu from './MarkdownDrawioUtil';
-import geu from './GridEditorUtil';
+import AbstractEditor from './AbstractEditor';
+import DrawioModal from './DrawioModal';
+import EditorIcon from './EditorIcon';
+import EmojiPicker from './EmojiPicker';
+import EmojiPickerHelper from './EmojiPickerHelper';
 import GridEditModal from './GridEditModal';
-import LinkEditModal from './LinkEditModal';
+import geu from './GridEditorUtil';
 import HandsontableModal from './HandsontableModal';
-import EditorIcon from './EditorIcon';
-import DrawioModal from './DrawioModal';
-import { UncontrolledCodeMirror } from '../UncontrolledCodeMirror';
+import LinkEditModal from './LinkEditModal';
+import mdu from './MarkdownDrawioUtil';
+import mlu from './MarkdownLinkUtil';
+import MarkdownTableInterceptor from './MarkdownTableInterceptor';
+import mtu from './MarkdownTableUtil';
+import pasteHelper from './PasteHelper';
+import PreventMarkdownListInterceptor from './PreventMarkdownListInterceptor';
+import SimpleCheatsheet from './SimpleCheatsheet';
+
+
 // Textlint
 window.JSHINT = JSHINT;
 window.kuromojin = { dicPath: '/static/dict' };
@@ -697,8 +697,8 @@ export default class CodeMirrorEditor extends AbstractEditor {
             <EmojiPicker
               onClose={() => this.setState({ isEmojiPickerShown: false })}
               emojiSearchText={emojiSearchText}
-              editor={this.getCodeMirror()}
               emojiPickerHelper={this.emojiPickerHelper}
+              isOpen={this.state.isEmojiPickerShown}
             />
           </div>
         </div>

+ 23 - 35
packages/app/src/components/PageEditor/EmojiPicker.tsx

@@ -1,7 +1,8 @@
-import React, { FC, useRef, useEffect } from 'react';
+import React, { FC } from 'react';
 
 import { Picker } from 'emoji-mart';
 import i18n from 'i18next';
+import { Modal } from 'reactstrap';
 
 import { isDarkMode } from '~/client/util/color-scheme';
 
@@ -10,46 +11,27 @@ import EmojiPickerHelper from './EmojiPickerHelper';
 type Props = {
   onClose: () => void,
   emojiSearchText: string,
-  editor: any
-  emojiPickerHelper: EmojiPickerHelper
+  emojiPickerHelper: EmojiPickerHelper,
+  isOpen: boolean
 }
 
 const EmojiPicker: FC<Props> = (props: Props) => {
 
   const {
-    onClose, emojiSearchText, emojiPickerHelper,
+    onClose, emojiSearchText, emojiPickerHelper, isOpen,
   } = props;
 
-  const emojiPickerContainer = useRef<HTMLDivElement>(null);
-
-  useEffect(() => {
-
-    if (emojiSearchText != null) {
-      // Get input element of emoji picker search
-      const input = document.querySelector('[id^="emoji-mart-search"]') as HTMLInputElement;
+  // Set search emoji input and trigger search
+  const searchEmoji = () => {
+    if (emojiSearchText !== null) {
+      const input = window.document.querySelector('[id^="emoji-mart-search"]') as HTMLInputElement;
       const valueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value')?.set;
-      // Set value to input of emoji picker search and trigger the search
       valueSetter?.call(input, emojiSearchText);
       const event = new Event('input', { bubbles: true });
       input.dispatchEvent(event);
+      input.focus();
     }
-  }, [emojiSearchText]);
-
-
-  // TODO: using blur event by GW-7770
-  useEffect(() => {
-    function handleClickOutside(event) {
-      if (emojiPickerContainer.current && !emojiPickerContainer.current.contains(event.target)) {
-        onClose();
-      }
-    }
-    document.addEventListener('mousedown', handleClickOutside);
-    return () => {
-      // Unbind the event listener on clean up
-      document.removeEventListener('mousedown', handleClickOutside);
-    };
-  }, [emojiPickerContainer, onClose]);
-
+  };
 
   const selectEmoji = (emoji) => {
     if (emojiSearchText !== null) {
@@ -58,7 +40,7 @@ const EmojiPicker: FC<Props> = (props: Props) => {
     else {
       emojiPickerHelper.addEmoji(emoji);
     }
-    props.onClose();
+    onClose();
   };
 
 
@@ -103,12 +85,18 @@ const EmojiPicker: FC<Props> = (props: Props) => {
 
   const translation = getEmojiTranslation();
   const theme = isDarkMode() ? 'dark' : 'light';
+
   return (
-    <div className="overlay">
-      <div ref={emojiPickerContainer}>
-        <Picker autoFocus onSelect={selectEmoji} i18n={translation} title={translation.title} emojiTooltip theme={theme} />
-      </div>
-    </div>
+    <Modal isOpen={isOpen} toggle={onClose} onOpened={searchEmoji}>
+      <Picker
+        onSelect={selectEmoji}
+        i18n={translation}
+        title={translation.title}
+        emojiTooltip
+        style={{ position: 'absolute' }}
+        theme={theme}
+      />
+    </Modal>
   );
 };