UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

145 lines • 7.49 kB
import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import React, { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react'; import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics/types/enums'; import { isOfflineMode } from '@atlaskit/editor-common/connectivity/isOfflineMode'; import { insertSelectedItem } from '@atlaskit/editor-common/insert'; import { MENU } from '@atlaskit/editor-common/quick-insert/keys'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/useSharedPluginStateWithSelector'; import { closeElementBrowser } from '../../pm-plugins/commands'; import { pluginKey } from '../../pm-plugins/plugin-key'; import { RegistryElementBrowser } from './RegistryElementBrowser'; var EMPTY_COMPONENTS = []; var subscribeToNothing = function subscribeToNothing() { return function () {}; }; export var RegistryElementBrowserContainer = function RegistryElementBrowserContainer(_ref) { var _pluginInjectionAPI$u2, _pluginInjectionAPI$u3, _pluginInjectionAPI$a2, _pluginKey$getState; var editorView = _ref.editorView, getRecommendedItems = _ref.getRecommendedItems, pluginInjectionAPI = _ref.pluginInjectionAPI, helpUrl = _ref.helpUrl; var _useSharedPluginState = useSharedPluginStateWithSelector(pluginInjectionAPI, ['quickInsert', 'connectivity'], function (state) { var _state$quickInsertSta, _state$quickInsertSta2, _state$quickInsertSta3, _state$connectivitySt; return { isElementBrowserOpen: (_state$quickInsertSta = (_state$quickInsertSta2 = state.quickInsertState) === null || _state$quickInsertSta2 === void 0 ? void 0 : _state$quickInsertSta2.isElementBrowserOpen) !== null && _state$quickInsertSta !== void 0 ? _state$quickInsertSta : false, emptyStateHandler: (_state$quickInsertSta3 = state.quickInsertState) === null || _state$quickInsertSta3 === void 0 ? void 0 : _state$quickInsertSta3.emptyStateHandler, mode: (_state$connectivitySt = state.connectivityState) === null || _state$connectivitySt === void 0 ? void 0 : _state$connectivitySt.mode }; }), currentEmptyStateHandler = _useSharedPluginState.emptyStateHandler, isElementBrowserOpen = _useSharedPluginState.isElementBrowserOpen, mode = _useSharedPluginState.mode; var getRegistrySnapshot = useCallback(function () { var _pluginInjectionAPI$u; if (!isElementBrowserOpen) { return EMPTY_COMPONENTS; } var components = pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$u = pluginInjectionAPI.uiControlRegistry) === null || _pluginInjectionAPI$u === void 0 ? void 0 : _pluginInjectionAPI$u.actions.getComponents(MENU.key); return components !== null && components !== void 0 && components.length ? components : EMPTY_COMPONENTS; }, [isElementBrowserOpen, pluginInjectionAPI]); var components = useSyncExternalStore(isElementBrowserOpen ? (_pluginInjectionAPI$u2 = pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$u3 = pluginInjectionAPI.uiControlRegistry) === null || _pluginInjectionAPI$u3 === void 0 ? void 0 : _pluginInjectionAPI$u3.actions.subscribe) !== null && _pluginInjectionAPI$u2 !== void 0 ? _pluginInjectionAPI$u2 : subscribeToNothing : subscribeToNothing, getRegistrySnapshot, getRegistrySnapshot); var _useState = useState(), _useState2 = _slicedToArray(_useState, 2), emptyStateHandler = _useState2[0], setEmptyStateHandler = _useState2[1]; var wasOpen = useRef(false); var selectionHandler = useRef(undefined); var isInsertConfirmed = useRef(false); var lifecycleOpen = useRef(false); var fireLifecycleEvent = useCallback(function (action) { var _pluginInjectionAPI$a; pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$a = pluginInjectionAPI.analytics) === null || _pluginInjectionAPI$a === void 0 || _pluginInjectionAPI$a.actions.fireAnalyticsEvent({ action: action, actionSubject: ACTION_SUBJECT.ELEMENT_BROWSER, attributes: { mode: 'full' }, eventType: EVENT_TYPE.UI }); }, [pluginInjectionAPI]); useEffect(function () { if (isElementBrowserOpen && !wasOpen.current) { selectionHandler.current = undefined; setEmptyStateHandler(function () { return currentEmptyStateHandler; }); isInsertConfirmed.current = false; lifecycleOpen.current = true; fireLifecycleEvent(ACTION.OPENED); } else if (!isElementBrowserOpen && wasOpen.current && lifecycleOpen.current) { lifecycleOpen.current = false; fireLifecycleEvent(ACTION.CLOSED); } wasOpen.current = isElementBrowserOpen; }, [currentEmptyStateHandler, fireLifecycleEvent, isElementBrowserOpen]); useEffect(function () { return function () { if (lifecycleOpen.current) { lifecycleOpen.current = false; fireLifecycleEvent(ACTION.CLOSED); } }; }, [fireLifecycleEvent]); var focusInEditor = useCallback(function () { if (!editorView.hasFocus()) { editorView.focus(); } }, [editorView]); var onClose = useCallback(function () { if (!isInsertConfirmed.current) { selectionHandler.current = undefined; } closeElementBrowser()(editorView.state, editorView.dispatch); focusInEditor(); }, [editorView, focusInEditor]); var onCloseComplete = useCallback(function () { var handler = isInsertConfirmed.current ? selectionHandler.current : undefined; selectionHandler.current = undefined; isInsertConfirmed.current = false; focusInEditor(); if (!handler) { return; } var insert = function insert(maybeNode) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return insertSelectedItem(maybeNode, options)(editorView.state, editorView.state.tr, editorView.state.selection.head); }; var transaction = handler({ insert: insert, source: INPUT_METHOD.ELEMENT_BROWSER }); if (transaction) { editorView.dispatch(transaction); } }, [editorView, focusInEditor]); var onSelect = useCallback(function (handler) { selectionHandler.current = handler; }, []); var onClearSelection = useCallback(function () { selectionHandler.current = undefined; isInsertConfirmed.current = false; }, []); var onConfirmInsert = useCallback(function () { if (!selectionHandler.current) { return; } isInsertConfirmed.current = true; onClose(); }, [onClose]); return /*#__PURE__*/React.createElement(RegistryElementBrowser, { components: components, fireAnalyticsEvent: pluginInjectionAPI === null || pluginInjectionAPI === void 0 || (_pluginInjectionAPI$a2 = pluginInjectionAPI.analytics) === null || _pluginInjectionAPI$a2 === void 0 ? void 0 : _pluginInjectionAPI$a2.actions.fireAnalyticsEvent, emptyStateHandler: emptyStateHandler, getRecommendedItems: getRecommendedItems, helpUrl: helpUrl, defaultSection: (_pluginKey$getState = pluginKey.getState(editorView.state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.elementBrowserInitialCategory, editorView: editorView, isOffline: isOfflineMode(mode), isOpen: isElementBrowserOpen, onClearSelection: onClearSelection, onClose: onClose, onCloseComplete: onCloseComplete, onConfirmInsert: onConfirmInsert, onSelect: onSelect }); };