UNPKG

@wordpress/block-editor

Version:
201 lines (181 loc) 5.72 kB
import { createElement } from "@wordpress/element"; /** * External dependencies */ import { View } from 'react-native'; /** * WordPress dependencies */ import { useEffect, useState, useCallback } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { createBlock, rawHandler, store as blocksStore } from '@wordpress/blocks'; import { BottomSheet, BottomSheetConsumer, getClipboard } from '@wordpress/components'; /** * Internal dependencies */ import InserterSearchResults from './search-results'; import InserterSearchForm from './search-form'; import { store as blockEditorStore } from '../../store'; import { searchItems } from './search-items'; const MIN_ITEMS_FOR_SEARCH = 2; function InserterMenu({ onSelect, onDismiss, rootClientId, clientId, isAppender, shouldReplaceBlock, insertionIndex }) { const [filterValue, setFilterValue] = useState(''); const [searchFormHeight, setSearchFormHeight] = useState(0); // eslint-disable-next-line no-undef const [showSearchForm, setShowSearchForm] = useState(__DEV__); const { showInsertionPoint, hideInsertionPoint, clearSelectedBlock, insertBlock, removeBlock, resetBlocks, insertDefaultBlock } = useDispatch(blockEditorStore); const { items, destinationRootClientId } = useSelect(select => { const { getInserterItems, getBlockRootClientId, getBlockSelectionEnd } = select(blockEditorStore); let targetRootClientId = rootClientId; if (!targetRootClientId && !clientId && !isAppender) { const end = getBlockSelectionEnd(); if (end) { targetRootClientId = getBlockRootClientId(end) || undefined; } } return { items: getInserterItems(targetRootClientId), destinationRootClientId: targetRootClientId }; }); const { getBlockOrder, getBlockCount, canInsertBlockType } = useSelect(blockEditorStore); const { getBlockType } = useSelect(blocksStore); useEffect(() => { var _getItems; // Show/Hide insertion point on Mount/Dismount if (shouldReplaceBlock) { const count = getBlockCount(); // Check if there is a rootClientId because that means it is a nested replaceable block // and we don't want to clear/reset all blocks. if (count === 1 && !rootClientId) { // Removing the last block is not possilble with `removeBlock` action. // It always inserts a default block if the last of the blocks have been removed. clearSelectedBlock(); resetBlocks([]); } else { const blockToReplace = getBlockOrder(destinationRootClientId)[insertionIndex]; removeBlock(blockToReplace, false); } } showInsertionPoint(destinationRootClientId, insertionIndex); // Show search form if there are enough items to filter. if (((_getItems = getItems()) === null || _getItems === void 0 ? void 0 : _getItems.length) < MIN_ITEMS_FOR_SEARCH) { setShowSearchForm(false); } return hideInsertionPoint; }, []); const onClose = useCallback(() => { // if should replace but didn't insert any block // re-insert default block if (shouldReplaceBlock) { insertDefaultBlock({}, destinationRootClientId, insertionIndex); } onDismiss(); }, [shouldReplaceBlock, destinationRootClientId, insertionIndex]); const onInsert = useCallback(item => { const { name, initialAttributes, innerBlocks } = item; const newBlock = createBlock(name, initialAttributes, innerBlocks); insertBlock(newBlock, insertionIndex, destinationRootClientId, true, { source: 'inserter_menu' }); }, [insertBlock, destinationRootClientId, insertionIndex]); /** * Processes the inserter items to check * if there's any copied block in the clipboard * to add it as an extra item */ function getItems() { var _clipboardBlock; // Filter out reusable blocks (they will be added in another tab) let itemsToDisplay = items.filter(({ name }) => name !== 'core/block'); itemsToDisplay = searchItems(itemsToDisplay, filterValue); const clipboard = getClipboard(); let clipboardBlock = rawHandler({ HTML: clipboard })[0]; const canAddClipboardBlock = canInsertBlockType((_clipboardBlock = clipboardBlock) === null || _clipboardBlock === void 0 ? void 0 : _clipboardBlock.name, destinationRootClientId); if (!canAddClipboardBlock) { return itemsToDisplay; } const { icon, name } = getBlockType(clipboardBlock.name); const { attributes: initialAttributes, innerBlocks } = clipboardBlock; clipboardBlock = { id: 'clipboard', name, icon, initialAttributes, innerBlocks }; return [clipboardBlock, ...itemsToDisplay]; } return createElement(BottomSheet, { isVisible: true, onClose: onClose, hideHeader: true, hasNavigation: true, setMinHeightToMaxHeight: showSearchForm }, createElement(BottomSheetConsumer, null, ({ listProps, safeAreaBottomInset }) => createElement(View, null, showSearchForm && createElement(InserterSearchForm, { onChange: value => { setFilterValue(value); }, value: filterValue, onLayout: event => { const { height } = event.nativeEvent.layout; setSearchFormHeight(height); } }), createElement(InserterSearchResults, { items: getItems(), onSelect: item => { onInsert(item); onSelect(item); }, listProps, safeAreaBottomInset, searchFormHeight })))); } export default InserterMenu; //# sourceMappingURL=menu.native.js.map