@wordpress/block-editor
Version:
238 lines (231 loc) • 10.5 kB
JavaScript
/**
* External dependencies
*/
import clsx from 'clsx';
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { useRef } from '@wordpress/element';
import { useViewportMatch } from '@wordpress/compose';
import { getBlockType, hasBlockSupport, isReusableBlock, isTemplatePart } from '@wordpress/blocks';
import { ToolbarGroup } from '@wordpress/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 __unstableBlockToolbarLastItem from './block-toolbar-last-item';
import BlockSettingsMenu from '../block-settings-menu';
import { BlockLockToolbar } from '../block-lock';
import { BlockGroupToolbar } from '../convert-to-group-buttons';
import BlockEditVisuallyButton from '../block-edit-visually-button';
import { useShowHoveredOrFocusedGestures } from './utils';
import { store as blockEditorStore } from '../../store';
import __unstableBlockNameContext from './block-name-context';
import NavigableToolbar from '../navigable-toolbar';
import { useHasBlockToolbar } from './use-has-block-toolbar';
import ChangeDesign from './change-design';
import SwitchSectionStyle from './switch-section-style';
import { unlock } from '../../lock-unlock';
/**
* Renders the block toolbar.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md
*
* @param {Object} props Components props.
* @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality.
* @param {boolean} props.focusOnMount Focus the toolbar when mounted.
* @param {number} props.__experimentalInitialIndex The initial index of the toolbar item to focus.
* @param {Function} props.__experimentalOnIndexChange Callback function to be called when the index of the focused toolbar item changes.
* @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons.
*/
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
export function PrivateBlockToolbar({
hideDragHandle,
focusOnMount,
__experimentalInitialIndex,
__experimentalOnIndexChange,
variant = 'unstyled'
}) {
const {
blockClientId,
blockClientIds,
isDefaultEditingMode,
blockType,
toolbarKey,
shouldShowVisualToolbar,
showParentSelector,
isUsingBindings,
hasParentPattern,
hasContentOnlyLocking,
showShuffleButton,
showSlots,
showGroupButtons,
showLockButtons,
showSwitchSectionStyleButton,
hasFixedToolbar,
isNavigationMode
} = useSelect(select => {
const {
getBlockName,
getBlockMode,
getBlockParents,
getSelectedBlockClientIds,
isBlockValid,
getBlockEditingMode,
getBlockAttributes,
getBlockParentsByBlockName,
getTemplateLock,
getSettings,
getParentSectionBlock,
isZoomOut,
isNavigationMode: _isNavigationMode
} = unlock(select(blockEditorStore));
const selectedBlockClientIds = getSelectedBlockClientIds();
const selectedBlockClientId = selectedBlockClientIds[0];
const parents = getBlockParents(selectedBlockClientId);
const parentSection = getParentSectionBlock(selectedBlockClientId);
const parentClientId = parentSection !== null && parentSection !== void 0 ? parentSection : parents[parents.length - 1];
const parentBlockName = getBlockName(parentClientId);
const parentBlockType = getBlockType(parentBlockName);
const editingMode = getBlockEditingMode(selectedBlockClientId);
const _isDefaultEditingMode = editingMode === 'default';
const _blockName = getBlockName(selectedBlockClientId);
const isValid = selectedBlockClientIds.every(id => isBlockValid(id));
const isVisual = selectedBlockClientIds.every(id => getBlockMode(id) === 'visual');
const _isUsingBindings = selectedBlockClientIds.every(clientId => !!getBlockAttributes(clientId)?.metadata?.bindings);
const _hasParentPattern = selectedBlockClientIds.every(clientId => getBlockParentsByBlockName(clientId, 'core/block', true).length > 0);
// If one or more selected blocks are locked, do not show the BlockGroupToolbar.
const _hasTemplateLock = selectedBlockClientIds.some(id => getTemplateLock(id) === 'contentOnly');
const _isZoomOut = isZoomOut();
return {
blockClientId: selectedBlockClientId,
blockClientIds: selectedBlockClientIds,
isDefaultEditingMode: _isDefaultEditingMode,
blockType: selectedBlockClientId && getBlockType(_blockName),
shouldShowVisualToolbar: isValid && isVisual,
toolbarKey: `${selectedBlockClientId}${parentClientId}`,
showParentSelector: !_isZoomOut && parentBlockType && editingMode !== 'contentOnly' && getBlockEditingMode(parentClientId) !== 'disabled' && hasBlockSupport(parentBlockType, '__experimentalParentSelector', true) && selectedBlockClientIds.length === 1,
isUsingBindings: _isUsingBindings,
hasParentPattern: _hasParentPattern,
hasContentOnlyLocking: _hasTemplateLock,
showShuffleButton: _isZoomOut,
showSlots: !_isZoomOut,
showGroupButtons: !_isZoomOut,
showLockButtons: !_isZoomOut,
showSwitchSectionStyleButton: _isZoomOut,
hasFixedToolbar: getSettings().hasFixedToolbar,
isNavigationMode: _isNavigationMode()
};
}, []);
const toolbarWrapperRef = useRef(null);
// Handles highlighting the current block outline on hover or focus of the
// block type toolbar area.
const nodeRef = useRef();
const showHoveredOrFocusedGestures = useShowHoveredOrFocusedGestures({
ref: nodeRef
});
const isLargeViewport = !useViewportMatch('medium', '<');
const hasBlockToolbar = useHasBlockToolbar();
if (!hasBlockToolbar) {
return null;
}
const isMultiToolbar = blockClientIds.length > 1;
const isSynced = isReusableBlock(blockType) || isTemplatePart(blockType);
// Shifts the toolbar to make room for the parent block selector.
const classes = clsx('block-editor-block-contextual-toolbar', {
'has-parent': showParentSelector,
'is-inverted-toolbar': isNavigationMode && !hasFixedToolbar
});
const innerClasses = clsx('block-editor-block-toolbar', {
'is-synced': isSynced,
'is-connected': isUsingBindings
});
return /*#__PURE__*/_jsx(NavigableToolbar, {
focusEditorOnEscape: true,
className: classes
/* translators: accessibility text for the block toolbar */,
"aria-label": __('Block tools')
// The variant is applied as "toolbar" when undefined, which is the black border style of the dropdown from the toolbar popover.
,
variant: variant === 'toolbar' ? undefined : variant,
focusOnMount: focusOnMount,
__experimentalInitialIndex: __experimentalInitialIndex,
__experimentalOnIndexChange: __experimentalOnIndexChange
// Resets the index whenever the active block changes so
// this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169
,
children: /*#__PURE__*/_jsxs("div", {
ref: toolbarWrapperRef,
className: innerClasses,
children: [showParentSelector && !isMultiToolbar && isLargeViewport && /*#__PURE__*/_jsx(BlockParentSelector, {}), (shouldShowVisualToolbar || isMultiToolbar) && !hasParentPattern && /*#__PURE__*/_jsx("div", {
ref: nodeRef,
...showHoveredOrFocusedGestures,
children: /*#__PURE__*/_jsxs(ToolbarGroup, {
className: "block-editor-block-toolbar__block-controls",
children: [/*#__PURE__*/_jsx(BlockSwitcher, {
clientIds: blockClientIds
}), !isMultiToolbar && isDefaultEditingMode && showLockButtons && /*#__PURE__*/_jsx(BlockLockToolbar, {
clientId: blockClientId
}), /*#__PURE__*/_jsx(BlockMover, {
clientIds: blockClientIds,
hideDragHandle: hideDragHandle
})]
})
}), !hasContentOnlyLocking && shouldShowVisualToolbar && isMultiToolbar && showGroupButtons && /*#__PURE__*/_jsx(BlockGroupToolbar, {}), showShuffleButton && /*#__PURE__*/_jsx(ChangeDesign, {
clientId: blockClientIds[0]
}), showSwitchSectionStyleButton && /*#__PURE__*/_jsx(SwitchSectionStyle, {
clientId: blockClientIds[0]
}), shouldShowVisualToolbar && showSlots && /*#__PURE__*/_jsxs(_Fragment, {
children: [/*#__PURE__*/_jsx(BlockControls.Slot, {
group: "parent",
className: "block-editor-block-toolbar__slot"
}), /*#__PURE__*/_jsx(BlockControls.Slot, {
group: "block",
className: "block-editor-block-toolbar__slot"
}), /*#__PURE__*/_jsx(BlockControls.Slot, {
className: "block-editor-block-toolbar__slot"
}), /*#__PURE__*/_jsx(BlockControls.Slot, {
group: "inline",
className: "block-editor-block-toolbar__slot"
}), /*#__PURE__*/_jsx(BlockControls.Slot, {
group: "other",
className: "block-editor-block-toolbar__slot"
}), /*#__PURE__*/_jsx(__unstableBlockNameContext.Provider, {
value: blockType?.name,
children: /*#__PURE__*/_jsx(__unstableBlockToolbarLastItem.Slot, {})
})]
}), /*#__PURE__*/_jsx(BlockEditVisuallyButton, {
clientIds: blockClientIds
}), /*#__PURE__*/_jsx(BlockSettingsMenu, {
clientIds: blockClientIds
})]
})
}, toolbarKey);
}
/**
* Renders the block toolbar.
*
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md
*
* @param {Object} props Components props.
* @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality.
* @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons.
*/
export default function BlockToolbar({
hideDragHandle,
variant
}) {
return /*#__PURE__*/_jsx(PrivateBlockToolbar, {
hideDragHandle: hideDragHandle,
variant: variant,
focusOnMount: undefined,
__experimentalInitialIndex: undefined,
__experimentalOnIndexChange: undefined
});
}
//# sourceMappingURL=index.js.map