From c0681a7c37e087d30f742f00a0b90a08fa6c12a8 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Tue, 5 Nov 2024 16:15:21 +0200 Subject: [PATCH 1/4] enable list view inspector control for controlling blocks in content only mode --- .../src/components/block-inspector/index.js | 47 ++++++++++++++++--- .../src/components/list-view/index.js | 4 +- .../list-view/use-list-view-client-ids.js | 13 +++-- .../src/store/private-selectors.js | 1 + packages/block-editor/src/store/selectors.js | 4 ++ .../src/navigation/edit/inner-blocks.js | 10 +++- 6 files changed, 66 insertions(+), 13 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index 475d4f6a4b8c2e..dfc7fae4788319 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -29,8 +29,10 @@ import useBlockInspectorAnimationSettings from './useBlockInspectorAnimationSett import BlockInfo from '../block-info-slot-fill'; import BlockQuickNavigation from '../block-quick-navigation'; import { useBorderPanelLabel } from '../../hooks/border'; +import { privateApis as blockEditorPrivateApis } from '../../private-apis'; import { unlock } from '../../lock-unlock'; +const { PrivateListView } = unlock( blockEditorPrivateApis ); function BlockStylesPanel( { clientId } ) { return ( @@ -223,6 +225,7 @@ const BlockInspectorSingleBlock = ( { }, [ blockName ] ); + const blockInformation = useBlockDisplayInformation( clientId ); const borderPanelLabel = useBorderPanelLabel( { blockName } ); const contentClientIds = useSelect( @@ -246,6 +249,20 @@ const BlockInspectorSingleBlock = ( { [ isSectionBlock, clientId ] ); + const { selectedContentClientId, isSelectedContentClientIdControlling } = + useSelect( ( select ) => { + const { getSelectedBlockClientId, areInnerBlocksControlled } = + select( blockEditorStore ); + + const _selectedBlockClientId = getSelectedBlockClientId(); + return { + selectedContentClientId: _selectedBlockClientId, + isSelectedContentClientIdControlling: areInnerBlocksControlled( + _selectedBlockClientId + ), + }; + } ); + return (
) } - { contentClientIds && contentClientIds?.length > 0 && ( - - - - ) } + { ! isSelectedContentClientIdControlling && + contentClientIds && + contentClientIds?.length > 0 && ( + + + + ) } + + { isSelectedContentClientIdControlling && + contentClientIds && + contentClientIds?.length > 0 && ( + + + + ) } { ! isSectionBlock && ( <> diff --git a/packages/block-editor/src/components/list-view/index.js b/packages/block-editor/src/components/list-view/index.js index d7961bd6c02f3d..a2b7ff80f072ab 100644 --- a/packages/block-editor/src/components/list-view/index.js +++ b/packages/block-editor/src/components/list-view/index.js @@ -78,6 +78,7 @@ export const BLOCK_LIST_ITEM_HEIGHT = 32; * @param {?HTMLElement} props.dropZoneElement Optional element to be used as the drop zone. * @param {?boolean} props.showBlockMovers Flag to enable block movers. Defaults to `false`. * @param {?boolean} props.isExpanded Flag to determine whether nested levels are expanded by default. Defaults to `false`. + * @param {?boolean} props.ignoreRenderingMode Flag to ignore rendering mode and always show the block. Defaults to `false`. * @param {?boolean} props.showAppender Flag to show or hide the block appender. Defaults to `false`. * @param {?ComponentType} props.blockSettingsMenu Optional more menu substitution. Defaults to the standard `BlockSettingsDropdown` component. * @param {string} props.rootClientId The client id of the root block from which we determine the blocks to show in the list. @@ -93,6 +94,7 @@ function ListViewComponent( dropZoneElement, showBlockMovers = false, isExpanded = false, + ignoreRenderingMode = false, showAppender = false, blockSettingsMenu: BlockSettingsMenu = BlockSettingsDropdown, rootClientId, @@ -115,7 +117,7 @@ function ListViewComponent( const instanceId = useInstanceId( ListViewComponent ); const { clientIdsTree, draggedClientIds, selectedClientIds } = - useListViewClientIds( { blocks, rootClientId } ); + useListViewClientIds( { blocks, rootClientId, ignoreRenderingMode } ); const blockIndexes = useListViewBlockIndexes( clientIdsTree ); const { getBlock } = useSelect( blockEditorStore ); diff --git a/packages/block-editor/src/components/list-view/use-list-view-client-ids.js b/packages/block-editor/src/components/list-view/use-list-view-client-ids.js index 8a1ccfcede4c12..0980818b418280 100644 --- a/packages/block-editor/src/components/list-view/use-list-view-client-ids.js +++ b/packages/block-editor/src/components/list-view/use-list-view-client-ids.js @@ -10,22 +10,29 @@ import { useSelect } from '@wordpress/data'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -export default function useListViewClientIds( { blocks, rootClientId } ) { +export default function useListViewClientIds( { + blocks, + rootClientId, + ignoreRenderingMode, +} ) { return useSelect( ( select ) => { const { getDraggedBlockClientIds, getSelectedBlockClientIds, getEnabledClientIdsTree, + __unstableGetClientIdsTree: getClientIdsTree, } = unlock( select( blockEditorStore ) ); return { selectedClientIds: getSelectedBlockClientIds(), draggedClientIds: getDraggedBlockClientIds(), clientIdsTree: - blocks ?? getEnabledClientIdsTree( rootClientId ), + blocks ?? ignoreRenderingMode + ? getClientIdsTree( rootClientId ) + : getEnabledClientIdsTree( rootClientId ), }; }, - [ blocks, rootClientId ] + [ blocks, rootClientId, ignoreRenderingMode ] ); } diff --git a/packages/block-editor/src/store/private-selectors.js b/packages/block-editor/src/store/private-selectors.js index f1b5abd7789a11..d8fbb87e6c12f6 100644 --- a/packages/block-editor/src/store/private-selectors.js +++ b/packages/block-editor/src/store/private-selectors.js @@ -90,6 +90,7 @@ function getEnabledClientIdsTreeUnmemoized( state, rootClientId ) { state, clientId ); + if ( getBlockEditingMode( state, clientId ) !== 'disabled' ) { result.push( { clientId, innerBlocks } ); } else { diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 598b6b4ea480de..82821706a74fb2 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -3046,6 +3046,10 @@ export const getBlockEditingMode = createRegistrySelector( clientId = ''; } + if ( areInnerBlocksControlled( state, clientId ) ) { + return 'contentOnly'; + } + // In zoom-out mode, override the behavior set by // __unstableSetBlockEditingMode to only allow editing the top-level // sections. diff --git a/packages/block-library/src/navigation/edit/inner-blocks.js b/packages/block-library/src/navigation/edit/inner-blocks.js index 6fe3dd8347a33e..e2534a20ed1bb5 100644 --- a/packages/block-library/src/navigation/edit/inner-blocks.js +++ b/packages/block-library/src/navigation/edit/inner-blocks.js @@ -73,6 +73,11 @@ export default function NavigationInnerBlocks( { const showPlaceholder = ! hasCustomPlaceholder && ! hasMenuItems && ! isSelected; + const defaultRenderingMode = useSelect( ( select ) => { + const { getBlockEditingMode } = select( blockEditorStore ); + return getBlockEditingMode( clientId ) === 'default'; + } ); + const innerBlocksProps = useInnerBlocksProps( { className: 'wp-block-navigation__container', @@ -93,13 +98,14 @@ export default function NavigationInnerBlocks( { // the sibling inserter. // See https://github.com/WordPress/gutenberg/issues/37572. renderAppender: - isSelected || + defaultRenderingMode && + ( isSelected || ( isImmediateParentOfSelectedBlock && ! selectedBlockHasChildren ) || // Show the appender while dragging to allow inserting element between item and the appender. parentOrChildHasSelection ? InnerBlocks.ButtonBlockAppender - : false, + : false ), placeholder: showPlaceholder ? placeholder : undefined, __experimentalCaptureToolbars: true, __unstableDisableLayoutClassNames: true, From 13172efbcd9d1b683e1342ec01d0764a76261ff0 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Wed, 6 Nov 2024 20:14:44 +0200 Subject: [PATCH 2/4] remove behavior from design mode --- .../src/components/block-inspector/index.js | 16 ++++++++++++++++ packages/block-editor/src/store/selectors.js | 8 ++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index dfc7fae4788319..e4eb91e1fc5a7d 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -262,6 +262,8 @@ const BlockInspectorSingleBlock = ( { ), }; } ); + const { __unstableGetEditorMode } = useSelect( blockEditorStore ); + const editorMode = __unstableGetEditorMode(); return (
@@ -311,6 +313,20 @@ const BlockInspectorSingleBlock = ( { { ! isSectionBlock && ( <> + { editorMode === 'navigation' && + isSelectedContentClientIdControlling && ( + + + + ) } Date: Mon, 11 Nov 2024 18:43:40 +0200 Subject: [PATCH 3/4] only show the off canvas list view for children of content only locked parents --- .../src/components/block-inspector/index.js | 45 ++++++++++++++----- packages/block-editor/src/store/selectors.js | 10 +++-- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index e4eb91e1fc5a7d..c59b0f4e822e4f 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -249,19 +249,38 @@ const BlockInspectorSingleBlock = ( { [ isSectionBlock, clientId ] ); - const { selectedContentClientId, isSelectedContentClientIdControlling } = - useSelect( ( select ) => { - const { getSelectedBlockClientId, areInnerBlocksControlled } = - select( blockEditorStore ); + const { + selectedContentClientId, + isSelectedContentClientIdControlling, + isSelectedBlockInContentOnlyContainer, + } = useSelect( ( select ) => { + const { + getSelectedBlockClientId, + areInnerBlocksControlled, + getBlockRootClientId, + getTemplateLock, + } = select( blockEditorStore ); + + const _selectedBlockClientId = getSelectedBlockClientId(); + const _isSelectedContentClientIdControlling = areInnerBlocksControlled( + _selectedBlockClientId + ); + + const rootClientId = getBlockRootClientId( _selectedBlockClientId ); + const templateLock = getTemplateLock( rootClientId ); + + const _isSelectedBlockInContentOnlyContainer = + templateLock === 'contentOnly'; - const _selectedBlockClientId = getSelectedBlockClientId(); - return { - selectedContentClientId: _selectedBlockClientId, - isSelectedContentClientIdControlling: areInnerBlocksControlled( - _selectedBlockClientId - ), - }; - } ); + return { + selectedContentClientId: _selectedBlockClientId, + isSelectedContentClientIdControlling: + _isSelectedContentClientIdControlling, + isSelectedBlockInContentOnlyContainer: + _isSelectedBlockInContentOnlyContainer, + hasContentLockedParent: false, + }; + } ); const { __unstableGetEditorMode } = useSelect( blockEditorStore ); const editorMode = __unstableGetEditorMode(); @@ -298,6 +317,7 @@ const BlockInspectorSingleBlock = ( { ) } { isSelectedContentClientIdControlling && + isSelectedBlockInContentOnlyContainer && contentClientIds && contentClientIds?.length > 0 && ( @@ -314,6 +334,7 @@ const BlockInspectorSingleBlock = ( { { ! isSectionBlock && ( <> { editorMode === 'navigation' && + isSelectedBlockInContentOnlyContainer && isSelectedContentClientIdControlling && ( Date: Tue, 12 Nov 2024 16:39:55 +0200 Subject: [PATCH 4/4] add contronlling blocks exception only when the context is content only --- .../src/components/block-inspector/index.js | 1 + packages/block-editor/src/store/selectors.js | 31 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/block-inspector/index.js b/packages/block-editor/src/components/block-inspector/index.js index c59b0f4e822e4f..5648cc2c6370f9 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -215,6 +215,7 @@ const BlockInspectorSingleBlock = ( { isSectionBlock, } ) => { const availableTabs = useInspectorControlsTabs( blockName ); + const showTabs = ! isSectionBlock && availableTabs?.length > 1; const hasBlockStyles = useSelect( diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 879667884bb86c..fb59a55e9b114c 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -3046,12 +3046,6 @@ export const getBlockEditingMode = createRegistrySelector( clientId = ''; } - // All controlling blocks are treated as content only - // by default. - if ( areInnerBlocksControlled( state, clientId ) ) { - return 'contentOnly'; - } - // In zoom-out mode, override the behavior set by // __unstableSetBlockEditingMode to only allow editing the top-level // sections. @@ -3074,6 +3068,12 @@ export const getBlockEditingMode = createRegistrySelector( return 'contentOnly'; } + // All controlling blocks are treated as content only + // by default. + if ( areInnerBlocksControlled( state, clientId ) ) { + return 'contentOnly'; + } + return 'disabled'; } @@ -3113,6 +3113,15 @@ export const getBlockEditingMode = createRegistrySelector( ); const isContent = hasContentRoleAttribute( name ); + // All controlling blocks are treated as content only + // by default. + if ( + ! isContent && + areInnerBlocksControlled( state, clientId ) + ) { + return 'contentOnly'; + } + return isContent ? 'contentOnly' : 'disabled'; } @@ -3136,6 +3145,16 @@ export const getBlockEditingMode = createRegistrySelector( select( blocksStore ) ); const isContent = hasContentRoleAttribute( name ); + + // All controlling blocks are treated as content only + // by default. + if ( + ! isContent && + areInnerBlocksControlled( state, clientId ) + ) { + return 'contentOnly'; + } + return isContent ? 'contentOnly' : 'disabled'; } // Otherwise, check if there's an ancestor that is contentOnly