From a1ca737442faab9e9b829b564013776da760e941 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 8 Aug 2023 17:58:39 +1000 Subject: [PATCH] Fix missing Replace button in content-locked Image blocks (#53410) * Revert "don't display BlockContextualToolbar at all in contentonly locking (#53110)" This reverts commit 5efce0ecec77fec764c30ce53f6368554ce9eb1a. * Alternative fix to hide BlockContextualToolbar when there are no controls --- .../block-controls/use-has-block-controls.js | 35 +++++++++++++++++++ .../block-tools/block-contextual-toolbar.js | 15 ++++---- .../src/components/block-tools/style.scss | 4 --- 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 packages/block-editor/src/components/block-controls/use-has-block-controls.js diff --git a/packages/block-editor/src/components/block-controls/use-has-block-controls.js b/packages/block-editor/src/components/block-controls/use-has-block-controls.js new file mode 100644 index 0000000000000..f7884cc1882ed --- /dev/null +++ b/packages/block-editor/src/components/block-controls/use-has-block-controls.js @@ -0,0 +1,35 @@ +/** + * WordPress dependencies + */ +import { __experimentalUseSlotFills as useSlotFills } from '@wordpress/components'; +import warning from '@wordpress/warning'; + +/** + * Internal dependencies + */ +import groups from './groups'; + +export function useHasAnyBlockControls() { + let hasAnyBlockControls = false; + for ( const group in groups ) { + // It is safe to violate the rules of hooks here as the `groups` object + // is static and will not change length between renders. Do not return + // early as that will cause the hook to be called a different number of + // times between renders. + // eslint-disable-next-line react-hooks/rules-of-hooks + if ( useHasBlockControls( group ) ) { + hasAnyBlockControls = true; + } + } + return hasAnyBlockControls; +} + +export function useHasBlockControls( group = 'default' ) { + const Slot = groups[ group ]?.Slot; + const fills = useSlotFills( Slot?.__unstableName ); + if ( ! Slot ) { + warning( `Unknown BlockControls group "${ group }" provided.` ); + return null; + } + return !! fills?.length; +} diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js index 7dcd88d1cfd10..9667cb21d99b7 100644 --- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js +++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js @@ -25,6 +25,7 @@ import NavigableToolbar from '../navigable-toolbar'; import BlockToolbar from '../block-toolbar'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; +import { useHasAnyBlockControls } from '../block-controls/use-has-block-controls'; function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { // When the toolbar is fixed it can be collapsed @@ -34,10 +35,10 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const isLargeViewport = useViewportMatch( 'medium' ); const { blockType, + blockEditingMode, hasParents, showParentSelector, selectedBlockClientId, - isContentOnly, } = useSelect( ( select ) => { const { getBlockName, @@ -58,9 +59,8 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { blockType: _selectedBlockClientId && getBlockType( getBlockName( _selectedBlockClientId ) ), + blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), hasParents: parents.length, - isContentOnly: - getBlockEditingMode( _selectedBlockClientId ) === 'contentOnly', showParentSelector: parentBlockType && getBlockEditingMode( firstParentClientId ) === 'default' && @@ -78,10 +78,13 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { setIsCollapsed( false ); }, [ selectedBlockClientId ] ); + const isToolbarEnabled = + ! blockType || + hasBlockSupport( blockType, '__experimentalToolbar', true ); + const hasAnyBlockControls = useHasAnyBlockControls(); if ( - isContentOnly || - ( blockType && - ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) + ! isToolbarEnabled || + ( blockEditingMode !== 'default' && ! hasAnyBlockControls ) ) { return null; } diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss index 7c1d305c4b6d2..87481c2bc09d4 100644 --- a/packages/block-editor/src/components/block-tools/style.scss +++ b/packages/block-editor/src/components/block-tools/style.scss @@ -121,10 +121,6 @@ } } - &:has(.block-editor-block-toolbar:empty) { - display: none; - } - // Add a scrim to the right of the collapsed button. &.is-collapsed::after { content: "";