From 5a5fef247aa16745125129e33bfe67b8c4f888d0 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 8 Aug 2023 14:37:40 +1000 Subject: [PATCH 1/2] Revert "don't display BlockContextualToolbar at all in contentonly locking (#53110)" This reverts commit 5efce0ecec77fec764c30ce53f6368554ce9eb1a. --- .../block-tools/block-contextual-toolbar.js | 78 +++++++++---------- 1 file changed, 35 insertions(+), 43 deletions(-) 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..f0fc28c7fbbd2 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 @@ -32,56 +32,48 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const toolbarButtonRef = useRef(); const isLargeViewport = useViewportMatch( 'medium' ); - const { - blockType, - hasParents, - showParentSelector, - selectedBlockClientId, - isContentOnly, - } = useSelect( ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - getBlockEditingMode, - } = unlock( select( blockEditorStore ) ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( _selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); + const { blockType, hasParents, showParentSelector, selectedBlockClientId } = + useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + getBlockEditingMode, + } = unlock( select( blockEditorStore ) ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( _selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); - return { - selectedBlockClientId: _selectedBlockClientId, - blockType: - _selectedBlockClientId && - getBlockType( getBlockName( _selectedBlockClientId ) ), - hasParents: parents.length, - isContentOnly: - getBlockEditingMode( _selectedBlockClientId ) === 'contentOnly', - showParentSelector: - parentBlockType && - getBlockEditingMode( firstParentClientId ) === 'default' && - hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ) && - selectedBlockClientIds.length <= 1 && - getBlockEditingMode( _selectedBlockClientId ) === 'default', - }; - }, [] ); + return { + selectedBlockClientId: _selectedBlockClientId, + blockType: + _selectedBlockClientId && + getBlockType( getBlockName( _selectedBlockClientId ) ), + hasParents: parents.length, + showParentSelector: + parentBlockType && + getBlockEditingMode( firstParentClientId ) === 'default' && + hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ) && + selectedBlockClientIds.length <= 1 && + getBlockEditingMode( _selectedBlockClientId ) === 'default', + }; + }, [] ); useEffect( () => { setIsCollapsed( false ); }, [ selectedBlockClientId ] ); if ( - isContentOnly || - ( blockType && - ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) + blockType && + ! hasBlockSupport( blockType, '__experimentalToolbar', true ) ) { return null; } From b96d46b07abd48053adb27dfae3415c1f80d5110 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Tue, 8 Aug 2023 15:46:09 +1000 Subject: [PATCH 2/2] Alternative fix to hide BlockContextualToolbar when there are no controls --- .../block-controls/use-has-block-controls.js | 35 ++++++++ .../block-tools/block-contextual-toolbar.js | 81 +++++++++++-------- .../src/components/block-tools/style.scss | 4 - 3 files changed, 81 insertions(+), 39 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 f0fc28c7fbbd2..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 @@ -32,48 +33,58 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) { const toolbarButtonRef = useRef(); const isLargeViewport = useViewportMatch( 'medium' ); - const { blockType, hasParents, showParentSelector, selectedBlockClientId } = - useSelect( ( select ) => { - const { - getBlockName, - getBlockParents, - getSelectedBlockClientIds, - getBlockEditingMode, - } = unlock( select( blockEditorStore ) ); - const { getBlockType } = select( blocksStore ); - const selectedBlockClientIds = getSelectedBlockClientIds(); - const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; - const parents = getBlockParents( _selectedBlockClientId ); - const firstParentClientId = parents[ parents.length - 1 ]; - const parentBlockName = getBlockName( firstParentClientId ); - const parentBlockType = getBlockType( parentBlockName ); + const { + blockType, + blockEditingMode, + hasParents, + showParentSelector, + selectedBlockClientId, + } = useSelect( ( select ) => { + const { + getBlockName, + getBlockParents, + getSelectedBlockClientIds, + getBlockEditingMode, + } = unlock( select( blockEditorStore ) ); + const { getBlockType } = select( blocksStore ); + const selectedBlockClientIds = getSelectedBlockClientIds(); + const _selectedBlockClientId = selectedBlockClientIds[ 0 ]; + const parents = getBlockParents( _selectedBlockClientId ); + const firstParentClientId = parents[ parents.length - 1 ]; + const parentBlockName = getBlockName( firstParentClientId ); + const parentBlockType = getBlockType( parentBlockName ); - return { - selectedBlockClientId: _selectedBlockClientId, - blockType: - _selectedBlockClientId && - getBlockType( getBlockName( _selectedBlockClientId ) ), - hasParents: parents.length, - showParentSelector: - parentBlockType && - getBlockEditingMode( firstParentClientId ) === 'default' && - hasBlockSupport( - parentBlockType, - '__experimentalParentSelector', - true - ) && - selectedBlockClientIds.length <= 1 && - getBlockEditingMode( _selectedBlockClientId ) === 'default', - }; - }, [] ); + return { + selectedBlockClientId: _selectedBlockClientId, + blockType: + _selectedBlockClientId && + getBlockType( getBlockName( _selectedBlockClientId ) ), + blockEditingMode: getBlockEditingMode( _selectedBlockClientId ), + hasParents: parents.length, + showParentSelector: + parentBlockType && + getBlockEditingMode( firstParentClientId ) === 'default' && + hasBlockSupport( + parentBlockType, + '__experimentalParentSelector', + true + ) && + selectedBlockClientIds.length <= 1 && + getBlockEditingMode( _selectedBlockClientId ) === 'default', + }; + }, [] ); useEffect( () => { setIsCollapsed( false ); }, [ selectedBlockClientId ] ); + const isToolbarEnabled = + ! blockType || + hasBlockSupport( blockType, '__experimentalToolbar', true ); + const hasAnyBlockControls = useHasAnyBlockControls(); if ( - 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: "";