UNPKG

@atlaskit/editor-plugin-quick-insert

Version:

Quick insert plugin for @atlaskit/editor-core

214 lines 9.84 kB
/* RegistryElementBrowser.tsx generated by @compiled/babel-plugin v3.0.2 */ import "./RegistryElementBrowser.compiled.css"; import { ax, ix } from "@compiled/react/runtime"; import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; import IconButton from '@atlaskit/button/icon/button'; import { MENU, RECOMMENDED_SECTION } from '@atlaskit/editor-common/quick-insert/keys'; import { getMenuFooterSectionKey } from '@atlaskit/editor-common/type-ahead-get-menu-footer-section-key'; import { getSectionOverflowItemKey } from '@atlaskit/editor-common/type-ahead-get-section-overflow-item-key'; import Heading from '@atlaskit/heading/heading'; import CrossIcon from '@atlaskit/icon/core/cross'; import ModalBody from '@atlaskit/modal-dialog/modal-body'; import Modal from '@atlaskit/modal-dialog/modal-dialog'; import ModalFooter from '@atlaskit/modal-dialog/modal-footer'; import ModalHeader from '@atlaskit/modal-dialog/modal-header'; import ModalTitle from '@atlaskit/modal-dialog/modal-title'; import ModalTransition from '@atlaskit/modal-dialog/modal-transition'; import { fg } from '@atlaskit/platform-feature-flags/fg'; import Textfield from '@atlaskit/textfield/text-field'; import { createRegistryElementBrowserModel, getInitialRegistryElementBrowserSection, getRegistryElementBrowserItems } from './model'; import { RegistryElementBrowserCategories } from './RegistryElementBrowserCategories'; import { RegistryElementBrowserFooter } from './RegistryElementBrowserFooter'; import { RegistryElementBrowserSearchResults } from './RegistryElementBrowserSearchResults'; const browserGridTemplateColumns = '182px minmax(0, 1fr)'; const categoryColumnGap = `calc(${"var(--ds-space-200, 16px)"} + ${"var(--ds-space-150, 12px)"})`; const browserLayoutStyles = null; const headerContentStyles = null; const headerSearchStyles = null; const resultsId = 'registry-element-browser-results'; const modalTestId = 'registry-element-browser-modal'; export const RegistryElementBrowser = ({ components, emptyStateHandler, defaultSection, helpUrl, editorView, isLoading = false, isOffline, isOpen, onClearSelection, onClose, onCloseComplete, onConfirmInsert, onSelect }) => { var _model$fallbackItems$, _model$fallbackItems; const { formatMessage } = useIntl(); const model = useMemo(() => createRegistryElementBrowserModel(components, { footerKey: getMenuFooterSectionKey(MENU.key), overflowKeys: new Set(components.filter(component => component.type === 'menu-section').map(component => getSectionOverflowItemKey(component.key))), recommendedSectionKey: RECOMMENDED_SECTION.key, rootKey: MENU.key }), [components]); const [query, setQuery] = useState(''); const [section, setSection] = useState(() => getInitialRegistryElementBrowserSection(model, defaultSection)); const [selectedKey, setSelectedKey] = useState(); const searchInputRef = useRef(null); const wasOpen = useRef(false); const previousIsOffline = useRef(isOffline); useEffect(() => { if (isOpen && !wasOpen.current) { setQuery(''); setSection(getInitialRegistryElementBrowserSection(model, defaultSection)); // This clears local visual state and the parent-held insertion handler together. // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates setSelectedKey(undefined); onClearSelection(); } wasOpen.current = isOpen; }, [defaultSection, isOpen, model, onClearSelection]); const items = useMemo(() => getRegistryElementBrowserItems({ formatMessage, model, query, section }), [formatMessage, model, query, section]); const resultCount = items.length || (!isLoading && query.trim() ? (_model$fallbackItems$ = (_model$fallbackItems = model.fallbackItems) === null || _model$fallbackItems === void 0 ? void 0 : _model$fallbackItems.length) !== null && _model$fallbackItems$ !== void 0 ? _model$fallbackItems$ : 0 : 0); useEffect(() => { if (previousIsOffline.current !== isOffline) { setSelectedKey(undefined); onClearSelection(); } previousIsOffline.current = isOffline; }, [isOffline, onClearSelection]); const onSearchChange = useCallback(event => { setQuery(event.currentTarget.value); setSelectedKey(undefined); onClearSelection(); }, [onClearSelection]); const onSectionClick = useCallback(event => { setQuery(''); setSection(event.currentTarget.dataset.section || undefined); setSelectedKey(undefined); onClearSelection(); }, [onClearSelection]); const onClearSearch = useCallback(() => { var _searchInputRef$curre; setQuery(''); setSelectedKey(undefined); onClearSelection(); (_searchInputRef$curre = searchInputRef.current) === null || _searchInputRef$curre === void 0 ? void 0 : _searchInputRef$curre.focus(); }, [onClearSelection]); const onRegistrySelect = useCallback((key, handler) => { setSelectedKey(key); onSelect(handler); }, [onSelect]); const onModalOpenComplete = useCallback(node => { node.style.borderRadius = "var(--ds-radius-large, 8px)"; const footer = node.querySelector(`[data-testid="${modalTestId}--footer"]`); footer === null || footer === void 0 ? void 0 : footer.style.setProperty('box-sizing', 'border-box'); footer === null || footer === void 0 ? void 0 : footer.style.setProperty('height', '64px'); footer === null || footer === void 0 ? void 0 : footer.style.setProperty('padding-block', "var(--ds-space-200, 16px)"); const scrollableBody = node.querySelector(`[data-testid="${modalTestId}--scrollable"]`); scrollableBody === null || scrollableBody === void 0 ? void 0 : scrollableBody.style.setProperty('border-block-start', 'none'); scrollableBody === null || scrollableBody === void 0 ? void 0 : scrollableBody.style.setProperty('border-block-end', 'none'); }, []); const onKeyDown = useCallback(event => { if (event.key === 'ArrowDown' || event.key === 'ArrowUp') { var _resultCollection$que; const resultCollection = event.currentTarget.ownerDocument.getElementById(resultsId); const options = Array.from((_resultCollection$que = resultCollection === null || resultCollection === void 0 ? void 0 : resultCollection.querySelectorAll('[role="option"]:not([aria-disabled="true"]):not([disabled])')) !== null && _resultCollection$que !== void 0 ? _resultCollection$que : []); const currentIndex = options.findIndex(option => option === event.currentTarget.ownerDocument.activeElement); const nextIndex = event.key === 'ArrowDown' ? currentIndex + 1 : currentIndex - 1; const nextOption = options.at(nextIndex); if (nextOption) { event.preventDefault(); nextOption.focus(); } return; } if (event.key === 'Escape') { event.preventDefault(); onClose(); return; } if (event.key === 'Enter' && selectedKey) { event.preventDefault(); onConfirmInsert(); } }, [onClose, onConfirmInsert, selectedKey]); return /*#__PURE__*/React.createElement(ModalTransition, null, isOpen && /*#__PURE__*/React.createElement(Modal, { label: formatMessage({ defaultMessage: 'Insert elements', id: 'editor.quick-insert.title' }), height: "664px", onClose: onClose, onCloseComplete: onCloseComplete, onOpenComplete: onModalOpenComplete, testId: modalTestId, width: "min(968px, calc(100vw - 32px))" }, /*#__PURE__*/React.createElement(ModalHeader, null, /*#__PURE__*/React.createElement("div", { className: ax(["_zulp1fka _1e0c11p5 _yv0e1xuv _1bsb1osq _lk4ji47z"]) }, fg('platform_dst_modal-dialog-use-modal-title') ? /*#__PURE__*/React.createElement(ModalTitle, null, formatMessage({ defaultMessage: 'Insert elements', id: 'editor.quick-insert.title' })) : /*#__PURE__*/React.createElement(Heading, { size: "medium" }, formatMessage({ defaultMessage: 'Insert elements', id: 'editor.quick-insert.title' })), /*#__PURE__*/React.createElement("div", { className: ax(["_zulp1ejb _4cvr1h6o _1e0c11p5 _yv0ehpfy _1bsb1osq"]) }, /*#__PURE__*/React.createElement(Textfield, { autoFocus: true, "aria-controls": resultsId, "aria-label": formatMessage({ defaultMessage: 'Search elements', id: 'editor.quick-insert.search' }), isCompact: true, name: "registry-element-browser-search", onChange: onSearchChange, onKeyDown: onKeyDown, ref: searchInputRef, value: query }), /*#__PURE__*/React.createElement(IconButton, { appearance: "subtle", icon: CrossIcon, label: formatMessage({ defaultMessage: 'Clear search', id: 'editor.quick-insert.clear-search' }), onClick: onClearSearch, spacing: "compact" })))), /*#__PURE__*/React.createElement(ModalBody, null, /*#__PURE__*/React.createElement("div", { className: ax(["_zulp1fka _1e0c11p5 _yv0e1xuv _lk4ji47z"]) }, /*#__PURE__*/React.createElement(RegistryElementBrowserCategories, { section: section, sections: model.sections, onSectionClick: onSectionClick }), /*#__PURE__*/React.createElement(RegistryElementBrowserSearchResults, { editorView: editorView, emptyStateHandler: emptyStateHandler, isLoading: isLoading, isOffline: isOffline, items: items, fallbackItems: model.fallbackItems, query: query, resultsId: resultsId, section: section, selectedKey: selectedKey, onKeyDown: onKeyDown, onSelect: onRegistrySelect }))), /*#__PURE__*/React.createElement(ModalFooter, null, /*#__PURE__*/React.createElement(RegistryElementBrowserFooter, { helpUrl: helpUrl, isInsertEnabled: Boolean(selectedKey), onClose: onClose, onConfirmInsert: onConfirmInsert, resultCount: resultCount })))); };