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

feat: convert select emoji to functional component

https://youtrack.weseek.co.jp/issue/GW-7652
- Rename EmojiPicker to Emoji
- Implement functional component to select emoji
- Change emoji search pattern
mudana 4 лет назад
Родитель
Сommit
98ad1ae547

+ 101 - 0
packages/app/src/components/PageEditor/Emoji.jsx

@@ -0,0 +1,101 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Picker } from 'emoji-mart';
+import { withTranslation } from 'react-i18next';
+
+class Emoji extends React.Component {
+
+  constructor(props) {
+    super(props);
+    this.emojiPicker = React.createRef();
+    this.handleClickOutside = this.handleClickOutside.bind(this);
+  }
+
+  componentDidUpdate(prevProps) {
+    if (this.props.emojiSearchText !== prevProps.emojiSearchText) {
+      if (this.props.emojiSearchText != null) {
+        // Get input element of emoji picker search
+        const input = document.querySelector('[id^="emoji-mart-search"]');
+        const valueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
+        // Set value to input of emoji picker search and trigger the search
+        valueSetter.call(input, this.props.emojiSearchText);
+        const event = new Event('input', { bubbles: true });
+        input.dispatchEvent(event);
+      }
+    }
+  }
+
+  getTranslation() {
+    const { t } = this.props;
+    const categories = {};
+    [
+      'search',
+      'recent',
+      'smileys',
+      'people',
+      'nature',
+      'foods',
+      'activity',
+      'places',
+      'objects',
+      'symbols',
+      'flags',
+      'custom',
+    ].forEach((category) => {
+      categories[category] = t(`emoji.categories.${category}`);
+    });
+
+    const skintones = {};
+    (Array.from(Array(6).keys())).forEach((tone) => {
+      skintones[tone + 1] = t(`emoji.skintones.${tone + 1}`);
+    });
+
+    const translation = {
+      search: t('emoji.search'),
+      clear: t('emoji.clear'),
+      notfound: t('emoji.notfound'),
+      skintext: t('emoji.skintext'),
+      categories,
+      categorieslabel: t('emoji.categorieslabel'),
+      skintones,
+    };
+    return translation;
+  }
+
+  componentDidMount() {
+    document.addEventListener('mousedown', this.handleClickOutside);
+  }
+
+  componentWillUnmount() {
+    document.removeEventListener('mousedown', this.handleClickOutside);
+  }
+
+  handleClickOutside(event) {
+    if (this.emojiPicker && !this.emojiPicker.current.contains(event.target)) {
+      this.props.close();
+    }
+  }
+
+
+  render() {
+    const { t } = this.props;
+    const i18n = this.getTranslation();
+    return (
+      <div className="overlay">
+        <div ref={this.emojiPicker}>
+          <Picker set="apple" autoFocus onSelect={this.props.selectEmoji} i18n={i18n} title={t('emoji.title')} />
+        </div>
+      </div>
+    );
+  }
+
+}
+
+Emoji.propTypes = {
+  t: PropTypes.func.isRequired,
+  close: PropTypes.func,
+  selectEmoji: PropTypes.func,
+  emojiSearchText: PropTypes.string,
+};
+
+export default withTranslation()(Emoji);

+ 9 - 93
packages/app/src/components/PageEditor/EmojiPicker.jsx

@@ -1,105 +1,21 @@
 import React from 'react';
 import PropTypes from 'prop-types';
-import { Picker } from 'emoji-mart';
-import { withTranslation } from 'react-i18next';
+import Emoji from './Emoji';
 
-class EmojiPicker extends React.Component {
-
-  constructor(props) {
-    super(props);
-    this.emojiPicker = React.createRef();
-    this.handleClickOutside = this.handleClickOutside.bind(this);
-    this.selectEmoji = this.selectEmoji.bind(this);
-  }
-
-  componentDidUpdate(prevProps) {
-    if (this.props.emojiSearchText !== prevProps.emojiSearchText) {
-      if (this.props.emojiSearchText != null) {
-        // Get input element of emoji picker search
-        const input = document.querySelector('[id^="emoji-mart-search"]');
-        const valueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set;
-        // Set value to input of emoji picker search and trigger the search
-        valueSetter.call(input, this.props.emojiSearchText);
-        const event = new Event('input', { bubbles: true });
-        input.dispatchEvent(event);
-      }
-    }
-  }
-
-  getTranslation() {
-    const { t } = this.props;
-    const categories = {};
-    [
-      'search',
-      'recent',
-      'smileys',
-      'people',
-      'nature',
-      'foods',
-      'activity',
-      'places',
-      'objects',
-      'symbols',
-      'flags',
-      'custom',
-    ].forEach((category) => {
-      categories[category] = t(`emoji.categories.${category}`);
-    });
-
-    const skintones = {};
-    (Array.from(Array(6).keys())).forEach((tone) => {
-      skintones[tone + 1] = t(`emoji.skintones.${tone + 1}`);
-    });
-
-    const translation = {
-      search: t('emoji.search'),
-      clear: t('emoji.clear'),
-      notfound: t('emoji.notfound'),
-      skintext: t('emoji.skintext'),
-      categories,
-      categorieslabel: t('emoji.categorieslabel'),
-      skintones,
-    };
-    return translation;
-  }
-
-  componentDidMount() {
-    document.addEventListener('mousedown', this.handleClickOutside);
-  }
-
-  componentWillUnmount() {
-    document.removeEventListener('mousedown', this.handleClickOutside);
-  }
-
-  handleClickOutside(event) {
-    if (this.emojiPicker && !this.emojiPicker.current.contains(event.target)) {
-      this.props.close();
-    }
-  }
-
-  selectEmoji(emoji) {
-    this.props.selectEmoji(emoji);
-  }
-
-  render() {
-    const { t } = this.props;
-    const i18n = this.getTranslation();
-    return (
-      <div className="overlay">
-        <div ref={this.emojiPicker}>
-          <Picker set="apple" autoFocus onSelect={this.selectEmoji} i18n={i18n} title={t('emoji.title')} />
-        </div>
+function EmojiPicker(props) {
+  return (
+    <div className="overlay">
+      <div>
+        <Emoji close={props.close} selectEmoji={props.selectEmoji} emojiSearchText={props.emojiSearchText} />
       </div>
-    );
-  }
-
+    </div>
+  );
 }
 
 EmojiPicker.propTypes = {
-  t: PropTypes.func.isRequired,
   close: PropTypes.func,
   selectEmoji: PropTypes.func,
   emojiSearchText: PropTypes.string,
 };
 
-export default withTranslation()(EmojiPicker);
+export default EmojiPicker;

+ 1 - 1
packages/app/src/components/PageEditor/EmojiPickerHelper.js

@@ -7,7 +7,7 @@ class EmojiPickerHelper {
   }
 
   getSearchCursor() {
-    const pattern = /:[^:\s]+(?<!:)$/;
+    const pattern = /:[^:\s]+/;
     const currentPos = this.editor.getCursor();
     const sc = this.editor.getSearchCursor(pattern, currentPos, { multiline: false });
     return sc;