UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

126 lines • 5.86 kB
import React, { useCallback, useEffect, useRef, useState } from 'react'; import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { isOfflineMode } from '@atlaskit/editor-common/connectivity/isOfflineMode'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'; import { insertSelectedItem } from '@atlaskit/editor-common/insert'; import { MENU } from '@atlaskit/editor-common/quick-insert/keys'; import { closeElementBrowser } from '../../pm-plugins/commands'; import { pluginKey } from '../../pm-plugins/plugin-key'; import { RegistryElementBrowser } from './RegistryElementBrowser'; export const RegistryElementBrowserContainer = ({ editorView, pluginInjectionAPI, helpUrl }) => { var _pluginKey$getState; const { emptyStateHandler: currentEmptyStateHandler, isElementBrowserOpen, mode } = useSharedPluginStateWithSelector(pluginInjectionAPI, ['quickInsert', 'connectivity'], 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 }; }); const [snapshot, setSnapshot] = useState([]); const [hasInitialized, setHasInitialized] = useState(false); const [emptyStateHandler, setEmptyStateHandler] = useState(); const wasOpen = useRef(false); const selectionHandler = useRef(undefined); const isInsertConfirmed = useRef(false); const lifecycleOpen = useRef(false); const fireLifecycleEvent = useCallback(action => { var _pluginInjectionAPI$a; pluginInjectionAPI === null || pluginInjectionAPI === void 0 ? void 0 : (_pluginInjectionAPI$a = pluginInjectionAPI.analytics) === null || _pluginInjectionAPI$a === void 0 ? void 0 : _pluginInjectionAPI$a.actions.fireAnalyticsEvent({ action, actionSubject: ACTION_SUBJECT.ELEMENT_BROWSER, attributes: { mode: 'full' }, eventType: EVENT_TYPE.UI }); }, [pluginInjectionAPI]); useEffect(() => { if (isElementBrowserOpen && !wasOpen.current) { var _pluginInjectionAPI$u, _pluginInjectionAPI$u2; setSnapshot((_pluginInjectionAPI$u = pluginInjectionAPI === null || pluginInjectionAPI === void 0 ? void 0 : (_pluginInjectionAPI$u2 = pluginInjectionAPI.uiControlRegistry) === null || _pluginInjectionAPI$u2 === void 0 ? void 0 : _pluginInjectionAPI$u2.actions.getComponents(MENU.key)) !== null && _pluginInjectionAPI$u !== void 0 ? _pluginInjectionAPI$u : []); setHasInitialized(true); selectionHandler.current = undefined; setEmptyStateHandler(() => 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, pluginInjectionAPI]); useEffect(() => () => { if (lifecycleOpen.current) { lifecycleOpen.current = false; fireLifecycleEvent(ACTION.CLOSED); } }, [fireLifecycleEvent]); const focusInEditor = useCallback(() => { if (!editorView.hasFocus()) { editorView.focus(); } }, [editorView]); const onClose = useCallback(() => { if (!isInsertConfirmed.current) { selectionHandler.current = undefined; } closeElementBrowser()(editorView.state, editorView.dispatch); focusInEditor(); }, [editorView, focusInEditor]); const onCloseComplete = useCallback(() => { const handler = isInsertConfirmed.current ? selectionHandler.current : undefined; selectionHandler.current = undefined; isInsertConfirmed.current = false; focusInEditor(); if (!handler) { return; } const insert = (maybeNode, options = {}) => insertSelectedItem(maybeNode, options)(editorView.state, editorView.state.tr, editorView.state.selection.head); const transaction = handler({ insert, source: INPUT_METHOD.ELEMENT_BROWSER }); if (transaction) { editorView.dispatch(transaction); } }, [editorView, focusInEditor]); const onSelect = useCallback(handler => { selectionHandler.current = handler; }, []); const onClearSelection = useCallback(() => { selectionHandler.current = undefined; isInsertConfirmed.current = false; }, []); const onConfirmInsert = useCallback(() => { if (!selectionHandler.current) { return; } isInsertConfirmed.current = true; onClose(); }, [onClose]); return /*#__PURE__*/React.createElement(RegistryElementBrowser, { components: snapshot, emptyStateHandler: emptyStateHandler, helpUrl: helpUrl, defaultSection: (_pluginKey$getState = pluginKey.getState(editorView.state)) === null || _pluginKey$getState === void 0 ? void 0 : _pluginKey$getState.elementBrowserInitialCategory, editorView: editorView, isOffline: isOfflineMode(mode), isLoading: !hasInitialized, isOpen: isElementBrowserOpen, onClearSelection: onClearSelection, onClose: onClose, onCloseComplete: onCloseComplete, onConfirmInsert: onConfirmInsert, onSelect: onSelect }); };