UNPKG

@gechiui/block-editor

Version:
218 lines (206 loc) 5.59 kB
/** * External dependencies */ import { castArray, flow, noop } from 'lodash'; /** * GeChiUI dependencies */ import { __, sprintf } from '@gechiui/i18n'; import { DropdownMenu, MenuGroup, MenuItem } from '@gechiui/components'; import { useSelect } from '@gechiui/data'; import { moreVertical } from '@gechiui/icons'; import { Children, cloneElement, useCallback } from '@gechiui/element'; import { serialize, store as blocksStore } from '@gechiui/blocks'; import { store as keyboardShortcutsStore } from '@gechiui/keyboard-shortcuts'; import { useCopyToClipboard } from '@gechiui/compose'; /** * Internal dependencies */ import BlockActions from '../block-actions'; import BlockModeToggle from './block-mode-toggle'; import BlockHTMLConvertButton from './block-html-convert-button'; import __unstableBlockSettingsMenuFirstItem from './block-settings-menu-first-item'; import BlockSettingsMenuControls from '../block-settings-menu-controls'; import { store as blockEditorStore } from '../../store'; const POPOVER_PROPS = { className: 'block-editor-block-settings-menu__popover', position: 'bottom right', isAlternate: true, }; function CopyMenuItem( { blocks, onCopy } ) { const ref = useCopyToClipboard( () => serialize( blocks ), onCopy ); return <MenuItem ref={ ref }>{ __( '复制' ) }</MenuItem>; } export function BlockSettingsDropdown( { clientIds, __experimentalSelectBlock, children, ...props } ) { const blockClientIds = castArray( clientIds ); const count = blockClientIds.length; const firstBlockClientId = blockClientIds[ 0 ]; const { onlyBlock, title } = useSelect( ( select ) => { const { getBlockCount, getBlockName } = select( blockEditorStore ); const { getBlockType } = select( blocksStore ); return { onlyBlock: 1 === getBlockCount(), title: getBlockType( getBlockName( firstBlockClientId ) ) ?.title, }; }, [ firstBlockClientId ] ); const shortcuts = useSelect( ( select ) => { const { getShortcutRepresentation } = select( keyboardShortcutsStore ); return { duplicate: getShortcutRepresentation( 'core/block-editor/duplicate' ), remove: getShortcutRepresentation( 'core/block-editor/remove' ), insertAfter: getShortcutRepresentation( 'core/block-editor/insert-after' ), insertBefore: getShortcutRepresentation( 'core/block-editor/insert-before' ), }; }, [] ); const updateSelection = useCallback( __experimentalSelectBlock ? async ( clientIdsPromise ) => { const ids = await clientIdsPromise; if ( ids && ids[ 0 ] ) { __experimentalSelectBlock( ids[ 0 ] ); } } : noop, [ __experimentalSelectBlock ] ); const label = sprintf( /* translators: %s: block name */ __( '删除 %s' ), title ); const removeBlockLabel = count === 1 ? label : __( '移除区块' ); return ( <BlockActions clientIds={ clientIds } __experimentalUpdateSelection={ ! __experimentalSelectBlock } > { ( { canDuplicate, canInsertDefaultBlock, canMove, canRemove, onDuplicate, onInsertAfter, onInsertBefore, onRemove, onCopy, onMoveTo, blocks, } ) => ( <DropdownMenu icon={ moreVertical } label={ __( '选项' ) } className="block-editor-block-settings-menu" popoverProps={ POPOVER_PROPS } noIcons { ...props } > { ( { onClose } ) => ( <> <MenuGroup> <__unstableBlockSettingsMenuFirstItem.Slot fillProps={ { onClose } } /> { count === 1 && ( <BlockHTMLConvertButton clientId={ firstBlockClientId } /> ) } <CopyMenuItem blocks={ blocks } onCopy={ onCopy } /> { canDuplicate && ( <MenuItem onClick={ flow( onClose, onDuplicate, updateSelection ) } shortcut={ shortcuts.duplicate } > { __( '创建副本' ) } </MenuItem> ) } { canInsertDefaultBlock && ( <> <MenuItem onClick={ flow( onClose, onInsertBefore ) } shortcut={ shortcuts.insertBefore } > { __( '在当前区块前插入' ) } </MenuItem> <MenuItem onClick={ flow( onClose, onInsertAfter ) } shortcut={ shortcuts.insertAfter } > { __( '在当前区块后插入' ) } </MenuItem> </> ) } { canMove && ! onlyBlock && ( <MenuItem onClick={ flow( onClose, onMoveTo ) } > { __( '移动至' ) } </MenuItem> ) } { count === 1 && ( <BlockModeToggle clientId={ firstBlockClientId } onToggle={ onClose } /> ) } </MenuGroup> <BlockSettingsMenuControls.Slot fillProps={ { onClose } } clientIds={ clientIds } /> { typeof children === 'function' ? children( { onClose } ) : Children.map( ( child ) => cloneElement( child, { onClose } ) ) } { canRemove && ( <MenuGroup> <MenuItem onClick={ flow( onClose, onRemove, updateSelection ) } shortcut={ shortcuts.remove } > { removeBlockLabel } </MenuItem> </MenuGroup> ) } </> ) } </DropdownMenu> ) } </BlockActions> ); } export default BlockSettingsDropdown;