UNPKG

@gechiui/block-editor

Version:
149 lines (136 loc) 4.16 kB
/** * External dependencies */ import classnames from 'classnames'; /** * GeChiUI dependencies */ import { useSelect, useDispatch } from '@gechiui/data'; import { useRef } from '@gechiui/element'; import { useViewportMatch } from '@gechiui/compose'; import { getBlockType, hasBlockSupport } from '@gechiui/blocks'; import { ToolbarGroup } from '@gechiui/components'; /** * Internal dependencies */ import BlockMover from '../block-mover'; import BlockParentSelector from '../block-parent-selector'; import BlockSwitcher from '../block-switcher'; import BlockControls from '../block-controls'; import BlockSettingsMenu from '../block-settings-menu'; import { useShowMoversGestures } from './utils'; import { store as blockEditorStore } from '../../store'; export default function BlockToolbar( { hideDragHandle } ) { const { blockClientIds, blockClientId, blockType, hasFixedToolbar, hasReducedUI, isValid, isVisual, } = useSelect( ( select ) => { const { getBlockName, getBlockMode, getSelectedBlockClientIds, isBlockValid, getBlockRootClientId, getSettings, } = select( blockEditorStore ); const selectedBlockClientIds = getSelectedBlockClientIds(); const selectedBlockClientId = selectedBlockClientIds[ 0 ]; const blockRootClientId = getBlockRootClientId( selectedBlockClientId ); const settings = getSettings(); return { blockClientIds: selectedBlockClientIds, blockClientId: selectedBlockClientId, blockType: selectedBlockClientId && getBlockType( getBlockName( selectedBlockClientId ) ), hasFixedToolbar: settings.hasFixedToolbar, hasReducedUI: settings.hasReducedUI, rootClientId: blockRootClientId, isValid: selectedBlockClientIds.every( ( id ) => isBlockValid( id ) ), isVisual: selectedBlockClientIds.every( ( id ) => getBlockMode( id ) === 'visual' ), }; }, [] ); // Handles highlighting the current block outline on hover or focus of the // block type toolbar area. const { toggleBlockHighlight } = useDispatch( blockEditorStore ); const nodeRef = useRef(); const { showMovers, gestures: showMoversGestures } = useShowMoversGestures( { ref: nodeRef, onChange( isFocused ) { if ( isFocused && hasReducedUI ) { return; } toggleBlockHighlight( blockClientId, isFocused ); }, } ); // Account for the cases where the block toolbar is rendered within the // header area and not contextually to the block. const displayHeaderToolbar = useViewportMatch( 'medium', '<' ) || hasFixedToolbar; if ( blockType ) { if ( ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) { return null; } } const shouldShowMovers = displayHeaderToolbar || showMovers; if ( blockClientIds.length === 0 ) { return null; } const shouldShowVisualToolbar = isValid && isVisual; const isMultiToolbar = blockClientIds.length > 1; const classes = classnames( 'block-editor-block-toolbar', shouldShowMovers && 'is-showing-movers' ); return ( <div className={ classes }> { ! isMultiToolbar && ! displayHeaderToolbar && ( <BlockParentSelector clientIds={ blockClientIds } /> ) } <div ref={ nodeRef } { ...showMoversGestures }> { ( shouldShowVisualToolbar || isMultiToolbar ) && ( <ToolbarGroup className="block-editor-block-toolbar__block-controls"> <BlockSwitcher clientIds={ blockClientIds } /> <BlockMover clientIds={ blockClientIds } hideDragHandle={ hideDragHandle || hasReducedUI } /> </ToolbarGroup> ) } </div> { shouldShowVisualToolbar && ( <> <BlockControls.Slot group="parent" className="block-editor-block-toolbar__slot" /> <BlockControls.Slot group="block" className="block-editor-block-toolbar__slot" /> <BlockControls.Slot className="block-editor-block-toolbar__slot" /> <BlockControls.Slot group="inline" className="block-editor-block-toolbar__slot" /> <BlockControls.Slot group="other" className="block-editor-block-toolbar__slot" /> </> ) } <BlockSettingsMenu clientIds={ blockClientIds } /> </div> ); }