UNPKG

@atlaskit/editor-plugin-emoji

Version:

Emoji plugin for @atlaskit/editor-core

170 lines 8.3 kB
import React, { useCallback, useEffect, useMemo } from 'react'; import { useIntl } from 'react-intl'; import { ACTION_SUBJECT_ID, INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { getDomRefFromSelection } from '@atlaskit/editor-common/get-dom-ref-from-selection'; import { useSharedPluginState } from '@atlaskit/editor-common/hooks'; import { Popup } from '@atlaskit/editor-common/ui'; import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react'; import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector'; import { akEditorFloatingDialogZIndex } from '@atlaskit/editor-shared-styles'; import { EmojiPicker } from '@atlaskit/emoji'; import { fg } from '@atlaskit/platform-feature-flags'; import { setInlineEmojiPopupOpen } from '../pm-plugins/actions'; const PopupWithListeners = withOuterListeners(Popup); const emojiPopupMessages = { emojiPickerAriaLabel: { id: 'fabric.emoji.picker.aria.label', defaultMessage: 'Emoji picker', description: 'Accessible label for the emoji picker popup' } }; export const InlineEmojiPopupOld = ({ api, popupsMountPoint, popupsBoundariesElement, popupsScrollableElement, editorView, onClose }) => { var _useSharedPluginState, _useSharedPluginState2, _api$analytics; const { emojiProvider, inlineEmojiPopupOpen: isOpen } = (_useSharedPluginState = (_useSharedPluginState2 = useSharedPluginState(api, ['emoji'])) === null || _useSharedPluginState2 === void 0 ? void 0 : _useSharedPluginState2.emojiState) !== null && _useSharedPluginState !== void 0 ? _useSharedPluginState : {}; const intl = useIntl(); useEffect(() => { if (isOpen && fg('platform_editor_ease_of_use_metrics')) { var _api$metrics; api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$metrics = api.metrics) === null || _api$metrics === void 0 ? void 0 : _api$metrics.commands.handleIntentToStartEdit({ shouldStartTimer: false, shouldPersistActiveSession: true })); } }, [isOpen, api]); const handleOnClose = useCallback(() => { if (fg('platform_editor_ease_of_use_metrics')) { var _api$metrics2; api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$metrics2 = api.metrics) === null || _api$metrics2 === void 0 ? void 0 : _api$metrics2.commands.startActiveSessionTimer()); } onClose === null || onClose === void 0 ? void 0 : onClose(); }, [onClose, api]); const focusEditor = useCallback(() => { // use requestAnimationFrame to run this async after the call requestAnimationFrame(() => editorView.focus()); }, [editorView]); const handleSelection = useCallback(emojiId => { api.core.actions.execute(api.emoji.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER)); handleOnClose(); }, [api.core.actions, api.emoji.commands, handleOnClose]); if (!isOpen || !emojiProvider) { return null; } const domRef = getDomRefFromSelection(editorView, ACTION_SUBJECT_ID.PICKER_EMOJI, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions); return /*#__PURE__*/React.createElement(PopupWithListeners, { ariaLabel: intl.formatMessage(emojiPopupMessages.emojiPickerAriaLabel) // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , offset: [0, 12], mountTo: popupsMountPoint, boundariesElement: popupsBoundariesElement, scrollableElement: popupsScrollableElement, zIndex: akEditorFloatingDialogZIndex, fitHeight: 350, fitWidth: 350, target: domRef, onUnmount: focusEditor, focusTrap: true, preventOverflow: true, handleClickOutside: handleOnClose, handleEscapeKeydown: handleOnClose, captureClick: true }, /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, setOutsideClickTargetRef => /*#__PURE__*/React.createElement(EmojiPicker, { emojiProvider: Promise.resolve(emojiProvider), onPickerRef: setOutsideClickTargetRef, onSelection: handleSelection }))); }; const InlineEmojiPopupContent = ({ api, popupsMountPoint, popupsBoundariesElement, popupsScrollableElement, editorView }) => { var _api$metrics4, _api$metrics6, _api$analytics3; const emojiProvider = useSharedPluginStateSelector(api, 'emoji.emojiProvider'); const intl = useIntl(); useEffect(() => { if (fg('platform_editor_ease_of_use_metrics')) { var _api$metrics3; api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$metrics3 = api.metrics) === null || _api$metrics3 === void 0 ? void 0 : _api$metrics3.commands.handleIntentToStartEdit({ shouldStartTimer: false, shouldPersistActiveSession: true })); } }, [api === null || api === void 0 ? void 0 : api.core.actions, api === null || api === void 0 ? void 0 : (_api$metrics4 = api.metrics) === null || _api$metrics4 === void 0 ? void 0 : _api$metrics4.commands]); const handleOnClose = useCallback(() => { editorView.dispatch(setInlineEmojiPopupOpen(false)(editorView.state.tr)); if (fg('platform_editor_ease_of_use_metrics')) { var _api$metrics5; api === null || api === void 0 ? void 0 : api.core.actions.execute(api === null || api === void 0 ? void 0 : (_api$metrics5 = api.metrics) === null || _api$metrics5 === void 0 ? void 0 : _api$metrics5.commands.startActiveSessionTimer()); } }, [editorView, api.core.actions, (_api$metrics6 = api.metrics) === null || _api$metrics6 === void 0 ? void 0 : _api$metrics6.commands]); const focusEditor = useCallback(() => { // use requestAnimationFrame to run this async after the call requestAnimationFrame(() => editorView.focus()); }, [editorView]); const handleSelection = useCallback(emojiId => { api.core.actions.execute(api.emoji.commands.insertEmoji(emojiId, INPUT_METHOD.PICKER)); handleOnClose(); }, [api.core.actions, api.emoji.commands, handleOnClose]); const domRef = useMemo(() => { var _api$analytics2; return getDomRefFromSelection(editorView, ACTION_SUBJECT_ID.PICKER_EMOJI, api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions); }, [editorView, api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions]); if (!emojiProvider) { return null; } return /*#__PURE__*/React.createElement(PopupWithListeners, { ariaLabel: intl.formatMessage(emojiPopupMessages.emojiPickerAriaLabel) // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , offset: [0, 12], mountTo: popupsMountPoint, boundariesElement: popupsBoundariesElement, scrollableElement: popupsScrollableElement, zIndex: akEditorFloatingDialogZIndex, fitHeight: 350, fitWidth: 350, target: domRef, onUnmount: focusEditor, focusTrap: true, preventOverflow: true, handleClickOutside: handleOnClose, handleEscapeKeydown: handleOnClose, captureClick: true }, /*#__PURE__*/React.createElement(OutsideClickTargetRefContext.Consumer, null, setOutsideClickTargetRef => /*#__PURE__*/React.createElement(EmojiPicker, { emojiProvider: Promise.resolve(emojiProvider), onPickerRef: setOutsideClickTargetRef, onSelection: handleSelection }))); }; export const InlineEmojiPopup = /*#__PURE__*/React.memo(({ api, popupsMountPoint, popupsBoundariesElement, popupsScrollableElement, editorView }) => { const isOpen = useSharedPluginStateSelector(api, 'emoji.inlineEmojiPopupOpen'); if (!isOpen) { return null; } return /*#__PURE__*/React.createElement(InlineEmojiPopupContent, { api: api, editorView: editorView, popupsBoundariesElement: popupsBoundariesElement, popupsMountPoint: popupsMountPoint, popupsScrollableElement: popupsScrollableElement }); });