UNPKG

@gechiui/block-editor

Version:
191 lines (172 loc) 6.82 kB
import { createElement, Fragment } from "@gechiui/element"; /** * External dependencies */ import { castArray, uniq } from 'lodash'; /** * GeChiUI dependencies */ import { __, _n, sprintf } from '@gechiui/i18n'; import { DropdownMenu, ToolbarButton, ToolbarGroup, ToolbarItem } from '@gechiui/components'; import { switchToBlockType, store as blocksStore, isReusableBlock, isTemplatePart } from '@gechiui/blocks'; import { useSelect, useDispatch } from '@gechiui/data'; import { stack } from '@gechiui/icons'; /** * Internal dependencies */ import { store as blockEditorStore } from '../../store'; import useBlockDisplayInformation from '../use-block-display-information'; import BlockIcon from '../block-icon'; import BlockTitle from '../block-title'; import BlockTransformationsMenu from './block-transformations-menu'; import BlockStylesMenu from './block-styles-menu'; import PatternTransformationsMenu from './pattern-transformations-menu'; export const BlockSwitcherDropdownMenu = _ref => { let { clientIds, blocks } = _ref; const { replaceBlocks } = useDispatch(blockEditorStore); const blockInformation = useBlockDisplayInformation(blocks[0].clientId); const { possibleBlockTransformations, canRemove, hasBlockStyles, icon, blockTitle, patterns } = useSelect(select => { var _getBlockType2; const { getBlockRootClientId, getBlockTransformItems, __experimentalGetPatternTransformItems } = select(blockEditorStore); const { getBlockStyles, getBlockType } = select(blocksStore); const { canRemoveBlocks } = select(blockEditorStore); const rootClientId = getBlockRootClientId(castArray(clientIds)[0]); const [{ name: firstBlockName }] = blocks; const _isSingleBlockSelected = blocks.length === 1; const styles = _isSingleBlockSelected && getBlockStyles(firstBlockName); let _icon; if (_isSingleBlockSelected) { _icon = blockInformation === null || blockInformation === void 0 ? void 0 : blockInformation.icon; // Take into account active block variations. } else { var _getBlockType; const isSelectionOfSameType = uniq(blocks.map(_ref2 => { let { name } = _ref2; return name; })).length === 1; // When selection consists of blocks of multiple types, display an // appropriate icon to communicate the non-uniformity. _icon = isSelectionOfSameType ? (_getBlockType = getBlockType(firstBlockName)) === null || _getBlockType === void 0 ? void 0 : _getBlockType.icon : stack; } return { possibleBlockTransformations: getBlockTransformItems(blocks, rootClientId), canRemove: canRemoveBlocks(clientIds, rootClientId), hasBlockStyles: !!(styles !== null && styles !== void 0 && styles.length), icon: _icon, blockTitle: (_getBlockType2 = getBlockType(firstBlockName)) === null || _getBlockType2 === void 0 ? void 0 : _getBlockType2.title, patterns: __experimentalGetPatternTransformItems(blocks, rootClientId) }; }, [clientIds, blocks, blockInformation === null || blockInformation === void 0 ? void 0 : blockInformation.icon]); const isReusable = blocks.length === 1 && isReusableBlock(blocks[0]); const isTemplate = blocks.length === 1 && isTemplatePart(blocks[0]); // Simple block tranformation based on the `Block Transforms` API. const onBlockTransform = name => replaceBlocks(clientIds, switchToBlockType(blocks, name)); // Pattern transformation through the `Patterns` API. const onPatternTransform = transformedBlocks => replaceBlocks(clientIds, transformedBlocks); const hasPossibleBlockTransformations = !!possibleBlockTransformations.length && canRemove; const hasPatternTransformation = !!(patterns !== null && patterns !== void 0 && patterns.length) && canRemove; if (!hasBlockStyles && !hasPossibleBlockTransformations) { return createElement(ToolbarGroup, null, createElement(ToolbarButton, { disabled: true, className: "block-editor-block-switcher__no-switcher-icon", title: blockTitle, icon: createElement(BlockIcon, { icon: icon, showColors: true }) })); } const blockSwitcherLabel = blockTitle; const blockSwitcherDescription = 1 === blocks.length ? sprintf( /* translators: %s: block title. */ __('%s:更改区块类型或样式'), blockTitle) : sprintf( /* translators: %d: number of blocks. */ _n('修改%d个区块的类型', 'Change type of %d blocks', blocks.length), blocks.length); const showDropDown = hasBlockStyles || hasPossibleBlockTransformations || hasPatternTransformation; return createElement(ToolbarGroup, null, createElement(ToolbarItem, null, toggleProps => createElement(DropdownMenu, { className: "block-editor-block-switcher", label: blockSwitcherLabel, popoverProps: { position: 'bottom right', isAlternate: true, className: 'block-editor-block-switcher__popover' }, icon: createElement(Fragment, null, createElement(BlockIcon, { icon: icon, className: "block-editor-block-switcher__toggle", showColors: true }), (isReusable || isTemplate) && createElement("span", { className: "block-editor-block-switcher__toggle-text" }, createElement(BlockTitle, { clientId: clientIds }))), toggleProps: { describedBy: blockSwitcherDescription, ...toggleProps }, menuProps: { orientation: 'both' } }, _ref3 => { let { onClose } = _ref3; return showDropDown && createElement("div", { className: "block-editor-block-switcher__container" }, hasPatternTransformation && createElement(PatternTransformationsMenu, { blocks: blocks, patterns: patterns, onSelect: transformedBlocks => { onPatternTransform(transformedBlocks); onClose(); } }), hasPossibleBlockTransformations && createElement(BlockTransformationsMenu, { className: "block-editor-block-switcher__transforms__menugroup", possibleBlockTransformations: possibleBlockTransformations, blocks: blocks, onSelect: name => { onBlockTransform(name); onClose(); } }), hasBlockStyles && createElement(BlockStylesMenu, { hoveredBlock: blocks[0], onSwitch: onClose })); }))); }; export const BlockSwitcher = _ref4 => { let { clientIds } = _ref4; const blocks = useSelect(select => select(blockEditorStore).getBlocksByClientId(clientIds), [clientIds]); if (!blocks.length || blocks.some(block => !block)) { return null; } return createElement(BlockSwitcherDropdownMenu, { clientIds: clientIds, blocks: blocks }); }; export default BlockSwitcher; //# sourceMappingURL=index.js.map