From 5b79516278d6eeced79aa473b0a9ea82795a1643 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 14:37:01 +0800 Subject: [PATCH 1/8] Allow list slot to render for sections --- .../src/components/block-inspector/index.js | 8 ++------ .../use-inspector-controls-tabs.js | 12 +++++------- 2 files changed, 7 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 47829930ff4f20..f029ee4f994cac 100644 --- a/packages/block-editor/src/components/block-inspector/index.js +++ b/packages/block-editor/src/components/block-inspector/index.js @@ -36,14 +36,12 @@ function StyleInspectorSlots( { blockName, showAdvancedControls = true, showPositionControls = true, - showListControls = false, showBindingsControls = true, } ) { const borderPanelLabel = useBorderPanelLabel( { blockName } ); return ( <> - { showListControls && } + { ! isSectionBlock && ( - + ) } { isSectionBlock && isBlockSynced && diff --git a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js index c86496510cc68b..ff871063cbaaeb 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js @@ -88,22 +88,20 @@ export default function useInspectorControlsTabs( hasContentFills || !! ( contentClientIds && contentClientIds.length > 0 ); - const hasListTab = hasListFills && ! isSectionBlock; + if ( hasContentTab ) { + tabs.push( TAB_CONTENT ); + } // Add the tabs in the order that they will default to if available. // List View > Content > Settings > Styles. - if ( hasListTab ) { + if ( hasListFills ) { tabs.push( TAB_LIST_VIEW ); } - if ( hasContentTab ) { - tabs.push( TAB_CONTENT ); - } - if ( ( settingsFills.length || // Advanded fills who up in settings tab if available or they blend into the default tab, if there's only one tab. - ( advancedFills.length && ( hasContentTab || hasListTab ) ) ) && + ( advancedFills.length && ( hasContentTab || hasListFills ) ) ) && ! isSectionBlock ) { tabs.push( TAB_SETTINGS ); From 02092e86611caef4b8478ae4bf8f5dc44d4b112d Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 14:37:28 +0800 Subject: [PATCH 2/8] Render list fills when a section is selected --- packages/block-editor/src/hooks/list-view.js | 30 +++++++++++++++++--- packages/block-editor/src/hooks/utils.js | 2 ++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/hooks/list-view.js b/packages/block-editor/src/hooks/list-view.js index 56111b926446d5..19146a327ef189 100644 --- a/packages/block-editor/src/hooks/list-view.js +++ b/packages/block-editor/src/hooks/list-view.js @@ -5,13 +5,15 @@ import { __ } from '@wordpress/i18n'; import { PanelBody } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { store as blocksStore, hasBlockSupport } from '@wordpress/blocks'; +import { useContext } from '@wordpress/element'; /** * Internal dependencies */ -import InspectorControls from '../components/inspector-controls'; import { store as blockEditorStore } from '../store'; import { PrivateListView } from '../components/list-view'; +import { PrivateInspectorControlsFill } from '../components/inspector-controls/fill'; +import { PrivateBlockContext } from '../components/block-list/private-block-context'; export const LIST_VIEW_SUPPORT_KEY = 'listView'; @@ -34,6 +36,8 @@ export function hasListViewSupport( nameOrType ) { * @return {Element|null} List view inspector controls or null. */ export function ListViewPanel( { clientId, name } ) { + const { isSelectionWithinCurrentSection, isSelected } = + useContext( PrivateBlockContext ); const isEnabled = hasListViewSupport( name ); const { hasChildren, blockTitle } = useSelect( ( select ) => ( { @@ -44,12 +48,29 @@ export function ListViewPanel( { clientId, name } ) { [ clientId, name ] ); - if ( ! isEnabled ) { + const notSelected = ! isSelected && ! isSelectionWithinCurrentSection; + + if ( notSelected || ! isEnabled ) { return null; } + if ( isSelectionWithinCurrentSection ) { + return ( + + + + + + ); + } + return ( - + { ! hasChildren && (

@@ -63,7 +84,7 @@ export function ListViewPanel( { clientId, name } ) { showAppender /> - + ); } @@ -74,4 +95,5 @@ export default { edit: ListViewPanel, hasSupport: hasListViewSupport, attributeKeys: [], + forceDisplayControls: true, }; diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index 464642b5bf7554..cbb69a7bb3adb0 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -534,8 +534,10 @@ export function createBlockEditFilter( features ) { hasSupport, attributeKeys = [], shareWithChildBlocks, + forceDisplayControls, } = feature; const shouldDisplayControls = + forceDisplayControls || context[ mayDisplayControlsKey ] || ( context[ mayDisplayParentControlsKey ] && shareWithChildBlocks ); From 2097bd89fb9340f85ecc74f9a3a90e6ad6b2bc72 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 15:51:45 +0800 Subject: [PATCH 3/8] Remove forceDisplayControls in favor of mayDisplayPatternEditingControls context value --- .../block-editor/src/components/block-edit/context.js | 3 +++ .../block-editor/src/components/block-edit/index.js | 5 +++++ .../block-editor/src/components/block-list/block.js | 3 +++ .../src/components/block-list/block.native.js | 5 +++++ .../src/components/inspector-controls/fill.js | 11 +++++++++-- packages/block-editor/src/hooks/block-fields/index.js | 5 +---- packages/block-editor/src/hooks/list-view.js | 2 +- 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index e1a1c1646eb53a..38394410686536 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -5,6 +5,9 @@ import { createContext, useContext } from '@wordpress/element'; export const mayDisplayControlsKey = Symbol( 'mayDisplayControls' ); export const mayDisplayParentControlsKey = Symbol( 'mayDisplayParentControls' ); +export const mayDisplayPatternEditingControlsKey = Symbol( + 'mayDisplayPatternEditingControls' +); export const blockEditingModeKey = Symbol( 'blockEditingMode' ); export const blockBindingsKey = Symbol( 'blockBindings' ); export const isPreviewModeKey = Symbol( 'isPreviewMode' ); diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index 0c29c0e98b1bfd..ed4aac7a0cfcda 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -13,6 +13,7 @@ import { useBlockEditContext, mayDisplayControlsKey, mayDisplayParentControlsKey, + mayDisplayPatternEditingControlsKey, blockEditingModeKey, blockBindingsKey, isPreviewModeKey, @@ -33,6 +34,7 @@ export { useBlockEditContext }; export default function BlockEdit( { mayDisplayControls, mayDisplayParentControls, + mayDisplayPatternEditingControls, blockEditingMode, isPreviewMode, // The remaining props are passed through the BlockEdit filters and are thus @@ -69,6 +71,8 @@ export default function BlockEdit( { // usage outside of the package (this context is exposed). [ mayDisplayControlsKey ]: mayDisplayControls, [ mayDisplayParentControlsKey ]: mayDisplayParentControls, + [ mayDisplayPatternEditingControlsKey ]: + mayDisplayPatternEditingControls, [ blockEditingModeKey ]: blockEditingMode, [ blockBindingsKey ]: bindings, [ isPreviewModeKey ]: isPreviewMode, @@ -82,6 +86,7 @@ export default function BlockEdit( { __unstableLayoutClassNames, mayDisplayControls, mayDisplayParentControls, + mayDisplayPatternEditingControls, blockEditingMode, bindings, isPreviewMode, diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 9dca3693a24c50..d782a89f9297e7 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -106,6 +106,7 @@ function BlockListBlock( { const { mayDisplayControls, mayDisplayParentControls, + isSelectionWithinCurrentSection, themeSupportsLayout, ...context } = useContext( PrivateBlockContext ); @@ -135,6 +136,7 @@ function BlockListBlock( { } mayDisplayControls={ mayDisplayControls } mayDisplayParentControls={ mayDisplayParentControls } + mayDisplayPatternEditingControls={ isSelectionWithinCurrentSection } blockEditingMode={ context.blockEditingMode } isPreviewMode={ context.isPreviewMode } /> @@ -231,6 +233,7 @@ function BlockListBlock( { value={ { wrapperProps: updatedWrapperProps, isAligned, + isSelectionWithinCurrentSection, ...context, } } > diff --git a/packages/block-editor/src/components/block-list/block.native.js b/packages/block-editor/src/components/block-list/block.native.js index 9f34195e50e040..463e4b531608b5 100644 --- a/packages/block-editor/src/components/block-list/block.native.js +++ b/packages/block-editor/src/components/block-list/block.native.js @@ -195,6 +195,7 @@ function BlockListBlock( { isParentSelected, order, mayDisplayControls, + mayDisplayPatternEditingControls, blockEditingMode, } = useSelect( ( select ) => { @@ -263,6 +264,7 @@ function BlockListBlock( { getMultiSelectedBlockClientIds().every( ( id ) => getBlockName( id ) === name ) ), + mayDisplayPatternEditingControls: false, // Section/pattern editing not yet supported on native blockEditingMode: getBlockEditingMode( clientId ), }; }, @@ -403,6 +405,9 @@ function BlockListBlock( { } wrapperProps={ wrapperProps } mayDisplayControls={ mayDisplayControls } + mayDisplayPatternEditingControls={ + mayDisplayPatternEditingControls + } blockEditingMode={ blockEditingMode } /> diff --git a/packages/block-editor/src/components/inspector-controls/fill.js b/packages/block-editor/src/components/inspector-controls/fill.js index 1663348e58fe7b..56fda7f8e3157e 100644 --- a/packages/block-editor/src/components/inspector-controls/fill.js +++ b/packages/block-editor/src/components/inspector-controls/fill.js @@ -15,6 +15,7 @@ import { useEffect, useContext } from '@wordpress/element'; import { useBlockEditContext, mayDisplayControlsKey, + mayDisplayPatternEditingControlsKey, } from '../block-edit/context'; import groups from './groups'; @@ -23,7 +24,6 @@ export function PrivateInspectorControlsFill( { group = 'default', __experimentalGroup, resetAllFilter, - forceDisplayControls, } ) { if ( __experimentalGroup ) { deprecated( @@ -43,7 +43,14 @@ export function PrivateInspectorControlsFill( { warning( `Unknown InspectorControls group "${ group }" provided.` ); return null; } - if ( ! forceDisplayControls && ! context[ mayDisplayControlsKey ] ) { + const shouldDisplayForPatternEditing = + context[ mayDisplayPatternEditingControlsKey ] && + ( group === 'list' || group === 'content' ); + + if ( + ! context[ mayDisplayControlsKey ] && + ! shouldDisplayForPatternEditing + ) { return null; } diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 82d7b7ddf57069..1ec4395f0d9b11 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -213,10 +213,7 @@ const withBlockFields = createHigherOrderComponent( isSelectionWithinCurrentSection && ( isSectionBlock || blockEditingMode === 'contentOnly' ) && ( - + + Date: Tue, 13 Jan 2026 15:59:18 +0800 Subject: [PATCH 4/8] Remove more hacks, add supportsPatternEditing property for blockedit hooks --- .../src/components/inspector-controls/fill.js | 19 +----------- .../src/hooks/block-fields/index.js | 10 +++--- packages/block-editor/src/hooks/list-view.js | 31 +++++-------------- packages/block-editor/src/hooks/utils.js | 6 ++-- 4 files changed, 18 insertions(+), 48 deletions(-) diff --git a/packages/block-editor/src/components/inspector-controls/fill.js b/packages/block-editor/src/components/inspector-controls/fill.js index 56fda7f8e3157e..0c613fe387b5f9 100644 --- a/packages/block-editor/src/components/inspector-controls/fill.js +++ b/packages/block-editor/src/components/inspector-controls/fill.js @@ -19,7 +19,7 @@ import { } from '../block-edit/context'; import groups from './groups'; -export function PrivateInspectorControlsFill( { +export default function InspectorControlsFill( { children, group = 'default', __experimentalGroup, @@ -71,23 +71,6 @@ export function PrivateInspectorControlsFill( { ); } -export default function InspectorControlsFill( { - children, - group = 'default', - __experimentalGroup, - resetAllFilter, -} ) { - return ( - - { children } - - ); -} - function RegisterResetAll( { resetAllFilter, children } ) { const { registerResetAllFilter, deregisterResetAllFilter } = useContext( ToolsPanelContext ); diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index 1ec4395f0d9b11..ecdf013f527c14 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -22,7 +22,7 @@ import useBlockDisplayInformation from '../../components/use-block-display-infor const { fieldsKey, formKey } = unlock( blocksPrivateApis ); import FieldsDropdownMenu from './fields-dropdown-menu'; import { PrivateBlockContext } from '../../components/block-list/private-block-context'; -import { PrivateInspectorControlsFill } from '../../components/inspector-controls/fill'; +import InspectorControls from '../../components/inspector-controls/fill'; // controls import RichText from './rich-text'; @@ -213,19 +213,19 @@ const withBlockFields = createHigherOrderComponent( isSelectionWithinCurrentSection && ( isSectionBlock || blockEditingMode === 'contentOnly' ) && ( - + - + ) } { ! isSelectionWithinCurrentSection && isSelected && ( - + - + ) } ); diff --git a/packages/block-editor/src/hooks/list-view.js b/packages/block-editor/src/hooks/list-view.js index c98d1966b3b4a0..95810887bc3f9b 100644 --- a/packages/block-editor/src/hooks/list-view.js +++ b/packages/block-editor/src/hooks/list-view.js @@ -12,7 +12,7 @@ import { useContext } from '@wordpress/element'; */ import { store as blockEditorStore } from '../store'; import { PrivateListView } from '../components/list-view'; -import { PrivateInspectorControlsFill } from '../components/inspector-controls/fill'; +import InspectorControls from '../components/inspector-controls/fill'; import { PrivateBlockContext } from '../components/block-list/private-block-context'; export const LIST_VIEW_SUPPORT_KEY = 'listView'; @@ -36,7 +36,7 @@ export function hasListViewSupport( nameOrType ) { * @return {Element|null} List view inspector controls or null. */ export function ListViewPanel( { clientId, name } ) { - const { isSelectionWithinCurrentSection, isSelected } = + const { isSelectionWithinCurrentSection } = useContext( PrivateBlockContext ); const isEnabled = hasListViewSupport( name ); const { hasChildren, blockTitle } = useSelect( @@ -48,30 +48,15 @@ export function ListViewPanel( { clientId, name } ) { [ clientId, name ] ); - const notSelected = ! isSelected && ! isSelectionWithinCurrentSection; - - if ( notSelected || ! isEnabled ) { + if ( ! isEnabled ) { return null; } - if ( isSelectionWithinCurrentSection ) { - return ( - - - - - - ); - } + const showBlockTitle = isSelectionWithinCurrentSection; return ( - - + + { ! hasChildren && (

{ __( 'No items yet.' ) } @@ -84,7 +69,7 @@ export function ListViewPanel( { clientId, name } ) { showAppender /> - + ); } @@ -95,5 +80,5 @@ export default { edit: ListViewPanel, hasSupport: hasListViewSupport, attributeKeys: [], - forceDisplayControls: true, + supportsPatternEditing: true, }; diff --git a/packages/block-editor/src/hooks/utils.js b/packages/block-editor/src/hooks/utils.js index cbb69a7bb3adb0..794b65f0523869 100644 --- a/packages/block-editor/src/hooks/utils.js +++ b/packages/block-editor/src/hooks/utils.js @@ -19,6 +19,7 @@ import { useBlockEditContext, mayDisplayControlsKey, mayDisplayParentControlsKey, + mayDisplayPatternEditingControlsKey, } from '../components/block-edit/context'; import { useSettings } from '../components'; import { useSettingsForBlockElement } from '../components/global-styles/hooks'; @@ -534,10 +535,11 @@ export function createBlockEditFilter( features ) { hasSupport, attributeKeys = [], shareWithChildBlocks, - forceDisplayControls, + supportsPatternEditing, } = feature; const shouldDisplayControls = - forceDisplayControls || + ( supportsPatternEditing && + context[ mayDisplayPatternEditingControlsKey ] ) || context[ mayDisplayControlsKey ] || ( context[ mayDisplayParentControlsKey ] && shareWithChildBlocks ); From a74668bfa1be84b88b0f2561349983f327f7245b Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 16:32:05 +0800 Subject: [PATCH 5/8] Ensure disabled blocks are not included in for blocks that mayDisplayPatternEditingControls --- packages/block-editor/src/components/block-edit/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-edit/index.js b/packages/block-editor/src/components/block-edit/index.js index ed4aac7a0cfcda..44ccb77fe96d3f 100644 --- a/packages/block-editor/src/components/block-edit/index.js +++ b/packages/block-editor/src/components/block-edit/index.js @@ -72,7 +72,8 @@ export default function BlockEdit( { [ mayDisplayControlsKey ]: mayDisplayControls, [ mayDisplayParentControlsKey ]: mayDisplayParentControls, [ mayDisplayPatternEditingControlsKey ]: - mayDisplayPatternEditingControls, + mayDisplayPatternEditingControls && + blockEditingMode !== 'disabled', [ blockEditingModeKey ]: blockEditingMode, [ blockBindingsKey ]: bindings, [ isPreviewModeKey ]: isPreviewMode, From ad4f94d781d2078ef82c619d0c63a960daabd2b6 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Tue, 13 Jan 2026 16:34:53 +0800 Subject: [PATCH 6/8] Port block fields to a proper BlockEdit hook --- .../src/hooks/block-fields/index.js | 93 ++++++++----------- packages/block-editor/src/hooks/index.js | 3 +- 2 files changed, 42 insertions(+), 54 deletions(-) diff --git a/packages/block-editor/src/hooks/block-fields/index.js b/packages/block-editor/src/hooks/block-fields/index.js index ecdf013f527c14..72fac94ee1ac27 100644 --- a/packages/block-editor/src/hooks/block-fields/index.js +++ b/packages/block-editor/src/hooks/block-fields/index.js @@ -1,13 +1,15 @@ /** * WordPress dependencies */ -import { addFilter } from '@wordpress/hooks'; -import { privateApis as blocksPrivateApis } from '@wordpress/blocks'; +import { + privateApis as blocksPrivateApis, + getBlockType, +} from '@wordpress/blocks'; import { __experimentalHStack as HStack, __experimentalTruncate as Truncate, } from '@wordpress/components'; -import { createHigherOrderComponent } from '@wordpress/compose'; +import { useSelect } from '@wordpress/data'; import { DataForm } from '@wordpress/dataviews'; import { useContext, useState, useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; @@ -15,6 +17,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ +import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; import BlockIcon from '../../components/block-icon'; import useBlockDisplayTitle from '../../components/block-title/use-block-display-title'; @@ -49,7 +52,6 @@ function createConfiguredControl( ControlComponent, config = {} ) { * @param {Object} props * @param {string} props.clientId The clientId of the block. * @param {Object} props.blockType The blockType definition. - * @param {Object} props.attributes The block's attribute values. * @param {Function} props.setAttributes Action to set the block's attributes. * @param {boolean} props.isCollapsed Whether the DataForm is rendered as 'collapsed' with only the first field * displayed by default. When collapsed a dropdown is displayed to allow @@ -59,7 +61,6 @@ function createConfiguredControl( ControlComponent, config = {} ) { function BlockFields( { clientId, blockType, - attributes, setAttributes, isCollapsed = false, } ) { @@ -71,6 +72,11 @@ function BlockFields( { const blockTypeFields = blockType?.[ fieldsKey ]; + const attributes = useSelect( + ( select ) => select( blockEditorStore ).getBlockAttributes( clientId ), + [ clientId ] + ); + const computedForm = useMemo( () => { if ( ! isCollapsed ) { return blockType?.[ formKey ]; @@ -187,53 +193,34 @@ function BlockFields( { ); } -const withBlockFields = createHigherOrderComponent( - ( BlockEdit ) => ( props ) => { - const { - blockType, - isSelectionWithinCurrentSection, - isSectionBlock, - blockEditingMode, - isSelected, - } = useContext( PrivateBlockContext ); - - const shouldShowBlockFields = - window?.__experimentalContentOnlyInspectorFields; - const blockTypeFields = blockType?.[ fieldsKey ]; - - if ( ! shouldShowBlockFields || ! blockTypeFields?.length ) { - return ; - } +function hasBlockFieldsSupport( blockName ) { + return !! ( + window?.__experimentalContentOnlyInspectorFields && + getBlockType( blockName )?.[ fieldsKey ] + ); +} - return ( - <> - - { - // Display the controls of all inner blocks for section/pattern editing. - isSelectionWithinCurrentSection && - ( isSectionBlock || - blockEditingMode === 'contentOnly' ) && ( - - - - ) - } - { ! isSelectionWithinCurrentSection && isSelected && ( - - - - ) } - - ); - } -); +export function BlockFieldsPanel( props ) { + const { blockType, isSelectionWithinCurrentSection } = + useContext( PrivateBlockContext ); -addFilter( - 'editor.BlockEdit', - 'core/content-only-controls/block-fields', - withBlockFields -); + return ( + + + + ); +} + +/** + * Export block support definition. + */ +export default { + edit: BlockFieldsPanel, + hasSupport: hasBlockFieldsSupport, + attributeKeys: [], + supportsPatternEditing: true, +}; diff --git a/packages/block-editor/src/hooks/index.js b/packages/block-editor/src/hooks/index.js index 21373ae3060768..be980ebd4c4fba 100644 --- a/packages/block-editor/src/hooks/index.js +++ b/packages/block-editor/src/hooks/index.js @@ -14,7 +14,7 @@ import './lock'; import allowedBlocks from './allowed-blocks'; import anchor from './anchor'; import ariaLabel from './aria-label'; -import './block-fields'; +import blockFields from './block-fields'; import customClassName from './custom-class-name'; import './generated-class-name'; import style from './style'; @@ -56,6 +56,7 @@ createBlockEditFilter( blockBindingsPanel, childLayout, allowedBlocks, + blockFields, listView, autoInspectorControls, ].filter( Boolean ) From ea030e65e914ddea7a61b14953a109bdc04dc7f9 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 15 Jan 2026 12:13:18 +0800 Subject: [PATCH 7/8] Fix empty content tab when there are no block fields in a pattern --- .../inspector-controls-tabs/use-inspector-controls-tabs.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js index ff871063cbaaeb..6f12636becc30a 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/use-inspector-controls-tabs.js @@ -84,9 +84,14 @@ export default function useInspectorControlsTabs( ...( hasListFills && hasStyleFills > 1 ? advancedFills : [] ), ]; + // When the block fields experiment is active, only rely on `hasContentFills` + // to determine whether the content tab to be shown. The tab purely uses slot + // fills in this situation. + const shouldShowBlockFields = + window?.__experimentalContentOnlyInspectorFields; const hasContentTab = hasContentFills || - !! ( contentClientIds && contentClientIds.length > 0 ); + ( ! shouldShowBlockFields && contentClientIds?.length ); if ( hasContentTab ) { tabs.push( TAB_CONTENT ); From 89554eee5b69de0137f56693bcf6008ca2a47b59 Mon Sep 17 00:00:00 2001 From: Daniel Richards Date: Thu, 15 Jan 2026 12:34:52 +0800 Subject: [PATCH 8/8] Only show top level List Views when pattern editing --- packages/block-editor/src/hooks/list-view.js | 39 ++++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/hooks/list-view.js b/packages/block-editor/src/hooks/list-view.js index 95810887bc3f9b..cb27e39a86cbd8 100644 --- a/packages/block-editor/src/hooks/list-view.js +++ b/packages/block-editor/src/hooks/list-view.js @@ -39,16 +39,39 @@ export function ListViewPanel( { clientId, name } ) { const { isSelectionWithinCurrentSection } = useContext( PrivateBlockContext ); const isEnabled = hasListViewSupport( name ); - const { hasChildren, blockTitle } = useSelect( - ( select ) => ( { - hasChildren: - !! select( blockEditorStore ).getBlockCount( clientId ), - blockTitle: select( blocksStore ).getBlockType( name )?.title, - } ), - [ clientId, name ] + const { hasChildren, blockTitle, isNestedListView } = useSelect( + ( select ) => { + const { getBlockCount, getBlockParents, getBlockName } = + select( blockEditorStore ); + + // When the ListView is shown in a section, avoid showing List Views + // for both parent and child blocks that have support. In this situation + // the parent will show the child anyway in its List. + // Search parents to see if there's one that also has support, and if so + // skip rendering. + // This matches closely the logic in the `BlockCard` component. + let _isNestedListView = false; + if ( isSelectionWithinCurrentSection ) { + const parents = getBlockParents( clientId, true ); + _isNestedListView = parents.find( ( parentId ) => { + const parentName = getBlockName( parentId ); + return ( + parentName === 'core/navigation' || + hasBlockSupport( parentName, 'listView' ) + ); + } ); + } + + return { + hasChildren: !! getBlockCount( clientId ), + blockTitle: select( blocksStore ).getBlockType( name )?.title, + isNestedListView: _isNestedListView, + }; + }, + [ clientId, name, isSelectionWithinCurrentSection ] ); - if ( ! isEnabled ) { + if ( ! isEnabled || isNestedListView ) { return null; }