From 4083d52b6a170500366f862bbe59db2344773e7d Mon Sep 17 00:00:00 2001 From: Ramon Date: Wed, 11 Feb 2026 16:19:48 +1100 Subject: [PATCH 1/8] Block Visibility: Show viewport icons and tooltip in list view for hidden blocks Co-Authored-By: Claude Opus 4.6 --- .../list-view/block-select-button.js | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index baa349f879ea75..aabbb06ab2e7a9 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -9,9 +9,11 @@ import clsx from 'clsx'; import { __experimentalHStack as HStack, __experimentalTruncate as Truncate, + Tooltip, privateApis as componentsPrivateApis, } from '@wordpress/components'; import { forwardRef } from '@wordpress/element'; +import { __, sprintf } from '@wordpress/i18n'; import { Icon, lockSmall as lock, @@ -33,6 +35,10 @@ import { useBlockLock } from '../block-lock'; import useListViewImages from './use-list-view-images'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; +import { + BLOCK_VISIBILITY_VIEWPORTS, + BLOCK_VISIBILITY_VIEWPORT_ENTRIES, +} from '../block-visibility/constants'; const { Badge } = unlock( componentsPrivateApis ); @@ -60,16 +66,17 @@ function ListViewBlockSelectButton( context: 'list-view', } ); const { isLocked } = useBlockLock( clientId ); - const { isBlockHidden, hasPatternName } = useSelect( + const { isBlockHidden, hasPatternName, blockVisibility } = useSelect( ( select ) => { const { isBlockHiddenAnywhere: _isBlockHidden, getBlockAttributes, } = unlock( select( blockEditorStore ) ); + const attributes = getBlockAttributes( clientId ); return { isBlockHidden: _isBlockHidden( clientId ), - hasPatternName: - !! getBlockAttributes( clientId )?.metadata?.patternName, + hasPatternName: !! attributes?.metadata?.patternName, + blockVisibility: attributes?.metadata?.blockVisibility, }; }, [ clientId ] @@ -79,6 +86,31 @@ function ListViewBlockSelectButton( const isSticky = blockInformation?.positionType === 'sticky'; const images = useListViewImages( { clientId, isExpanded } ); + // Determine which viewports the block is hidden on. + let hiddenViewports = []; + if ( isBlockHidden ) { + if ( blockVisibility === false ) { + hiddenViewports = Object.values( BLOCK_VISIBILITY_VIEWPORTS ); + } else if ( blockVisibility?.viewport ) { + hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( + ( [ key ] ) => blockVisibility.viewport[ key ] === false + ).map( ( [ , viewport ] ) => viewport ); + } + } + + let visibilityLabel; + if ( isBlockHidden ) { + if ( blockVisibility === false ) { + visibilityLabel = __( 'Hidden on all viewports' ); + } else if ( hiddenViewports.length > 0 ) { + visibilityLabel = sprintf( + /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + __( 'Hidden on %s' ), + hiddenViewports.map( ( v ) => v.label ).join( ', ' ) + ); + } + } + // The `href` attribute triggers the browser's native HTML drag operations. // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html. // We need to clear any HTML drag data to prevent `pasteHandler` from firing @@ -162,9 +194,19 @@ function ListViewBlockSelectButton( ) : null } { isBlockHidden && ( - - - + + + + { blockVisibility !== false && + hiddenViewports.map( ( viewport ) => ( + + ) ) } + + ) } { shouldShowLockIcon && ( From 76685ab87256f0697f7ebc6107900d03357e50ea Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 11:38:59 +1100 Subject: [PATCH 2/8] Only display currently-hidden viewport icon. Update tooltip to display current viewport icon for hidden blocks. --- .../list-view/block-select-button.js | 60 ++++++++++--------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index aabbb06ab2e7a9..ab6a1a3a5c494b 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -35,10 +35,9 @@ import { useBlockLock } from '../block-lock'; import useListViewImages from './use-list-view-images'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import { - BLOCK_VISIBILITY_VIEWPORTS, - BLOCK_VISIBILITY_VIEWPORT_ENTRIES, -} from '../block-visibility/constants'; +import { BLOCK_VISIBILITY_VIEWPORTS } from '../block-visibility/constants'; +import useBlockVisibility from '../block-visibility/use-block-visibility'; +import { deviceTypeKey } from '../../store/private-keys'; const { Badge } = unlock( componentsPrivateApis ); @@ -66,17 +65,26 @@ function ListViewBlockSelectButton( context: 'list-view', } ); const { isLocked } = useBlockLock( clientId ); - const { isBlockHidden, hasPatternName, blockVisibility } = useSelect( + const { + isBlockHidden, + hasPatternName, + blockVisibility, + selectedDeviceType, + } = useSelect( ( select ) => { const { isBlockHiddenAnywhere: _isBlockHidden, getBlockAttributes, + getSettings, } = unlock( select( blockEditorStore ) ); const attributes = getBlockAttributes( clientId ); return { isBlockHidden: _isBlockHidden( clientId ), hasPatternName: !! attributes?.metadata?.patternName, blockVisibility: attributes?.metadata?.blockVisibility, + selectedDeviceType: + getSettings()?.[ deviceTypeKey ]?.toLowerCase() || + BLOCK_VISIBILITY_VIEWPORTS.desktop.value, }; }, [ clientId ] @@ -86,27 +94,25 @@ function ListViewBlockSelectButton( const isSticky = blockInformation?.positionType === 'sticky'; const images = useListViewImages( { clientId, isExpanded } ); - // Determine which viewports the block is hidden on. - let hiddenViewports = []; - if ( isBlockHidden ) { - if ( blockVisibility === false ) { - hiddenViewports = Object.values( BLOCK_VISIBILITY_VIEWPORTS ); - } else if ( blockVisibility?.viewport ) { - hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( - ( [ key ] ) => blockVisibility.viewport[ key ] === false - ).map( ( [ , viewport ] ) => viewport ); - } - } + // Use hook to get current viewport and if block is currently hidden + const { isBlockCurrentlyHidden, currentViewport } = useBlockVisibility( { + blockVisibility, + deviceType: selectedDeviceType, + } ); + // Determine visibility label and current viewport icon let visibilityLabel; + let currentViewportIcon; if ( isBlockHidden ) { if ( blockVisibility === false ) { visibilityLabel = __( 'Hidden on all viewports' ); - } else if ( hiddenViewports.length > 0 ) { + } else if ( isBlockCurrentlyHidden && currentViewport ) { + const viewport = BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]; + currentViewportIcon = viewport?.icon; visibilityLabel = sprintf( - /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + /* translators: %s: viewport name (Desktop, Tablet, Mobile) */ __( 'Hidden on %s' ), - hiddenViewports.map( ( v ) => v.label ).join( ', ' ) + viewport?.label || currentViewport ); } } @@ -195,16 +201,14 @@ function ListViewBlockSelectButton( ) : null } { isBlockHidden && ( - + ) } From 67b22758c9c810f6ed233ca5db9cb56fd60f6b3b Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 12:11:04 +1100 Subject: [PATCH 3/8] Update tooltip to display visibility status for hidden blocks based on specific viewports, replacing the previous viewport icon logic. --- .../list-view/block-select-button.js | 51 +++++++------------ 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index ab6a1a3a5c494b..26be504917f87c 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -35,9 +35,7 @@ import { useBlockLock } from '../block-lock'; import useListViewImages from './use-list-view-images'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import { BLOCK_VISIBILITY_VIEWPORTS } from '../block-visibility/constants'; -import useBlockVisibility from '../block-visibility/use-block-visibility'; -import { deviceTypeKey } from '../../store/private-keys'; +import { BLOCK_VISIBILITY_VIEWPORT_ENTRIES } from '../block-visibility/constants'; const { Badge } = unlock( componentsPrivateApis ); @@ -65,26 +63,17 @@ function ListViewBlockSelectButton( context: 'list-view', } ); const { isLocked } = useBlockLock( clientId ); - const { - isBlockHidden, - hasPatternName, - blockVisibility, - selectedDeviceType, - } = useSelect( + const { isBlockHidden, hasPatternName, blockVisibility } = useSelect( ( select ) => { const { isBlockHiddenAnywhere: _isBlockHidden, getBlockAttributes, - getSettings, } = unlock( select( blockEditorStore ) ); const attributes = getBlockAttributes( clientId ); return { isBlockHidden: _isBlockHidden( clientId ), hasPatternName: !! attributes?.metadata?.patternName, blockVisibility: attributes?.metadata?.blockVisibility, - selectedDeviceType: - getSettings()?.[ deviceTypeKey ]?.toLowerCase() || - BLOCK_VISIBILITY_VIEWPORTS.desktop.value, }; }, [ clientId ] @@ -94,26 +83,25 @@ function ListViewBlockSelectButton( const isSticky = blockInformation?.positionType === 'sticky'; const images = useListViewImages( { clientId, isExpanded } ); - // Use hook to get current viewport and if block is currently hidden - const { isBlockCurrentlyHidden, currentViewport } = useBlockVisibility( { - blockVisibility, - deviceType: selectedDeviceType, - } ); - - // Determine visibility label and current viewport icon + // Determine visibility label from blockVisibility metadata let visibilityLabel; - let currentViewportIcon; if ( isBlockHidden ) { if ( blockVisibility === false ) { + // Hidden on all viewports visibilityLabel = __( 'Hidden on all viewports' ); - } else if ( isBlockCurrentlyHidden && currentViewport ) { - const viewport = BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]; - currentViewportIcon = viewport?.icon; - visibilityLabel = sprintf( - /* translators: %s: viewport name (Desktop, Tablet, Mobile) */ - __( 'Hidden on %s' ), - viewport?.label || currentViewport - ); + } else if ( blockVisibility?.viewport ) { + // Hidden on specific viewports - list them + const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( + ( [ key ] ) => blockVisibility.viewport[ key ] === false + ).map( ( [ , viewport ] ) => viewport.label ); + + if ( hiddenViewports.length > 0 ) { + visibilityLabel = sprintf( + /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + __( 'Hidden on %s' ), + hiddenViewports.join( ', ' ) + ); + } } } @@ -199,16 +187,13 @@ function ListViewBlockSelectButton( ) ) } ) : null } - { isBlockHidden && ( + { isBlockHidden && visibilityLabel && ( ) } From 1add7d13570bef275bbd197dbf24e5af02f723e3 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 12:17:16 +1100 Subject: [PATCH 4/8] Ensures that the tooltip (visual) and the aria description (a11y) match --- .../src/components/list-view/block.js | 90 +++++++++++-------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index e05036e6e07aa7..9e104025254806 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -54,9 +54,7 @@ import { useBlockRename, BlockRenameModal } from '../block-rename'; import AriaReferencedText from './aria-referenced-text'; import { unlock } from '../../lock-unlock'; import usePasteStyles from '../use-paste-styles'; -import { useBlockVisibility } from '../block-visibility'; -import { deviceTypeKey } from '../../store/private-keys'; -import { BLOCK_VISIBILITY_VIEWPORTS } from '../block-visibility/constants'; +import { BLOCK_VISIBILITY_VIEWPORT_ENTRIES } from '../block-visibility/constants'; function ListViewBlock( { block: { clientId }, @@ -127,50 +125,66 @@ function ListViewBlock( { const pasteStyles = usePasteStyles(); - const { block, blockName, allowRightClickOverrides, selectedDeviceType } = - useSelect( - ( select ) => { - const { getBlock, getBlockName, getSettings } = unlock( - select( blockEditorStore ) - ); + const { block, blockName, allowRightClickOverrides } = useSelect( + ( select ) => { + const { getBlock, getBlockName, getSettings } = unlock( + select( blockEditorStore ) + ); - return { - block: getBlock( clientId ), - blockName: getBlockName( clientId ), - allowRightClickOverrides: - getSettings().allowRightClickOverrides, - selectedDeviceType: - getSettings()?.[ deviceTypeKey ]?.toLowerCase() || - BLOCK_VISIBILITY_VIEWPORTS.desktop.value, - }; - }, - [ clientId ] - ); + return { + block: getBlock( clientId ), + blockName: getBlockName( clientId ), + allowRightClickOverrides: + getSettings().allowRightClickOverrides, + }; + }, + [ clientId ] + ); const { canRename } = useBlockRename( blockName ); - // Use hook to get current viewport and if block is currently hidden (accurate viewport detection) - const { isBlockCurrentlyHidden, currentViewport } = useBlockVisibility( { - blockVisibility: block?.attributes?.metadata?.blockVisibility, - deviceType: selectedDeviceType, - } ); - // Determine label based on whether block or parent is hidden + const { isBlockHiddenAnywhere } = useSelect( + ( select ) => { + return { + isBlockHiddenAnywhere: unlock( + select( blockEditorStore ) + ).isBlockHiddenAnywhere( clientId ), + }; + }, + [ clientId ] + ); + + // Determine label based on where block is hidden (not when/current viewport) const blockVisibilityDescription = useMemo( () => { - if ( isBlockCurrentlyHidden ) { - if ( block?.attributes?.metadata?.blockVisibility === false ) { - return __( 'Block is hidden' ); + if ( ! isBlockHiddenAnywhere ) { + return null; + } + + const blockVisibility = block?.attributes?.metadata?.blockVisibility; + + if ( blockVisibility === false ) { + // Hidden on all viewports + return __( 'Block is hidden' ); + } + + if ( blockVisibility?.viewport ) { + // Hidden on specific viewports - list them + const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( + ( [ key ] ) => blockVisibility.viewport[ key ] === false + ).map( ( [ , viewport ] ) => viewport.label ); + + if ( hiddenViewports.length > 0 ) { + return sprintf( + /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + __( 'Block is hidden on %s' ), + hiddenViewports.join( ', ' ) + ); } - return sprintf( - /* translators: %s: viewport name (Desktop, Tablet, Mobile) */ - __( 'Block is hidden on %s' ), - BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]?.label || - currentViewport - ); } + return null; }, [ - isBlockCurrentlyHidden, + isBlockHiddenAnywhere, block?.attributes?.metadata?.blockVisibility, - currentViewport, ] ); const showBlockActions = From 56c3d5e2ca7e4da12d6a8f159cdea95609b1d843 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 12:20:08 +1100 Subject: [PATCH 5/8] Update visibility label for hidden blocks in list view to improve clarity --- .../src/components/list-view/block-select-button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index 26be504917f87c..cbc2a58efb277c 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -88,7 +88,7 @@ function ListViewBlockSelectButton( if ( isBlockHidden ) { if ( blockVisibility === false ) { // Hidden on all viewports - visibilityLabel = __( 'Hidden on all viewports' ); + visibilityLabel = __( 'Block is hidden' ); } else if ( blockVisibility?.viewport ) { // Hidden on specific viewports - list them const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( From c1c5b0d1824df98ce1e2c87c5bf94c4c854654c1 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 12:28:43 +1100 Subject: [PATCH 6/8] Remove unnecessary state checks --- .../list-view/block-select-button.js | 40 ++++++++----------- .../src/components/list-view/block.js | 25 +++--------- 2 files changed, 23 insertions(+), 42 deletions(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index cbc2a58efb277c..612c9954a5772f 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -63,15 +63,11 @@ function ListViewBlockSelectButton( context: 'list-view', } ); const { isLocked } = useBlockLock( clientId ); - const { isBlockHidden, hasPatternName, blockVisibility } = useSelect( + const { hasPatternName, blockVisibility } = useSelect( ( select ) => { - const { - isBlockHiddenAnywhere: _isBlockHidden, - getBlockAttributes, - } = unlock( select( blockEditorStore ) ); + const { getBlockAttributes } = unlock( select( blockEditorStore ) ); const attributes = getBlockAttributes( clientId ); return { - isBlockHidden: _isBlockHidden( clientId ), hasPatternName: !! attributes?.metadata?.patternName, blockVisibility: attributes?.metadata?.blockVisibility, }; @@ -85,23 +81,21 @@ function ListViewBlockSelectButton( // Determine visibility label from blockVisibility metadata let visibilityLabel; - if ( isBlockHidden ) { - if ( blockVisibility === false ) { - // Hidden on all viewports - visibilityLabel = __( 'Block is hidden' ); - } else if ( blockVisibility?.viewport ) { - // Hidden on specific viewports - list them - const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( - ( [ key ] ) => blockVisibility.viewport[ key ] === false - ).map( ( [ , viewport ] ) => viewport.label ); + if ( blockVisibility === false ) { + // Hidden on all viewports + visibilityLabel = __( 'Block is hidden' ); + } else if ( blockVisibility?.viewport ) { + // Hidden on specific viewports - list them + const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( + ( [ key ] ) => blockVisibility.viewport?.[ key ] === false + ).map( ( [ , viewport ] ) => viewport.label ); - if ( hiddenViewports.length > 0 ) { - visibilityLabel = sprintf( - /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ - __( 'Hidden on %s' ), - hiddenViewports.join( ', ' ) - ); - } + if ( hiddenViewports.length > 0 ) { + visibilityLabel = sprintf( + /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + __( 'Hidden on %s' ), + hiddenViewports.join( ', ' ) + ); } } @@ -187,7 +181,7 @@ function ListViewBlockSelectButton( ) ) } ) : null } - { isBlockHidden && visibilityLabel && ( + { visibilityLabel && ( { - return { - isBlockHiddenAnywhere: unlock( - select( blockEditorStore ) - ).isBlockHiddenAnywhere( clientId ), - }; - }, - [ clientId ] - ); - // Determine label based on where block is hidden (not when/current viewport) const blockVisibilityDescription = useMemo( () => { - if ( ! isBlockHiddenAnywhere ) { + const blockVisibility = block?.attributes?.metadata?.blockVisibility; + + // Not hidden at all + if ( ! blockVisibility && blockVisibility !== false ) { return null; } - const blockVisibility = block?.attributes?.metadata?.blockVisibility; - if ( blockVisibility === false ) { // Hidden on all viewports return __( 'Block is hidden' ); @@ -169,7 +159,7 @@ function ListViewBlock( { if ( blockVisibility?.viewport ) { // Hidden on specific viewports - list them const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( - ( [ key ] ) => blockVisibility.viewport[ key ] === false + ( [ key ] ) => blockVisibility.viewport?.[ key ] === false ).map( ( [ , viewport ] ) => viewport.label ); if ( hiddenViewports.length > 0 ) { @@ -182,10 +172,7 @@ function ListViewBlock( { } return null; - }, [ - isBlockHiddenAnywhere, - block?.attributes?.metadata?.blockVisibility, - ] ); + }, [ block?.attributes?.metadata?.blockVisibility ] ); const showBlockActions = // When a block hides its toolbar it also hides the block settings menu, From 9129aa28535d60cbf0eb71af9618c1f81564f7a7 Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 12:59:14 +1100 Subject: [PATCH 7/8] Add getBlockVisibilityLabel utility function and refactor visibility label logic in list view components - Introduced `getBlockVisibilityLabel` function to generate human-readable labels for block visibility based on viewport settings. - Refactored visibility label determination in `ListViewBlockSelectButton` and `ListViewBlock` components to utilize the new utility function, improving code clarity and maintainability. --- .../src/components/block-visibility/index.js | 1 + .../src/components/block-visibility/utils.js | 40 ++++++++++++++++++ .../list-view/block-select-button.js | 22 +--------- .../src/components/list-view/block.js | 41 ++++--------------- 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/packages/block-editor/src/components/block-visibility/index.js b/packages/block-editor/src/components/block-visibility/index.js index 69b89e2c9497e6..fc79da9ce01592 100644 --- a/packages/block-editor/src/components/block-visibility/index.js +++ b/packages/block-editor/src/components/block-visibility/index.js @@ -3,3 +3,4 @@ export { default as useBlockVisibility } from './use-block-visibility'; export { default as ViewportVisibilityToolbar } from './viewport-toolbar'; export { default as BlockVisibilityViewportMenuItem } from './viewport-menu-item'; export { default as ViewportVisibilityInfo } from './viewport-visibility-info'; +export { getBlockVisibilityLabel } from './utils'; diff --git a/packages/block-editor/src/components/block-visibility/utils.js b/packages/block-editor/src/components/block-visibility/utils.js index 460283ea291e0b..c026a22f47893e 100644 --- a/packages/block-editor/src/components/block-visibility/utils.js +++ b/packages/block-editor/src/components/block-visibility/utils.js @@ -1,3 +1,8 @@ +/** + * WordPress dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; + /** * Internal dependencies */ @@ -101,3 +106,38 @@ export function getHideEverywhereCheckboxState( blocks ) { return null; // Indeterminate: some but not all } + +/** + * Get a human-readable label describing which viewports a block is hidden on. + * + * @param {boolean|Object} blockVisibility The block's visibility metadata. + * @return {string|null} A descriptive label, or null if the block is not hidden. + */ +export function getBlockVisibilityLabel( blockVisibility ) { + // Not hidden at all + if ( ! blockVisibility && blockVisibility !== false ) { + return null; + } + + if ( blockVisibility === false ) { + // Hidden on all viewports + return __( 'Block is hidden' ); + } + + if ( blockVisibility?.viewport ) { + // Hidden on specific viewports - list them + const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( + ( [ key ] ) => blockVisibility.viewport?.[ key ] === false + ).map( ( [ , viewport ] ) => viewport.label ); + + if ( hiddenViewports.length > 0 ) { + return sprintf( + /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ + __( 'Block is hidden on %s' ), + hiddenViewports.join( ', ' ) + ); + } + } + + return null; +} diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index 612c9954a5772f..f6d99ce5654a28 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -13,7 +13,6 @@ import { privateApis as componentsPrivateApis, } from '@wordpress/components'; import { forwardRef } from '@wordpress/element'; -import { __, sprintf } from '@wordpress/i18n'; import { Icon, lockSmall as lock, @@ -35,7 +34,7 @@ import { useBlockLock } from '../block-lock'; import useListViewImages from './use-list-view-images'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; -import { BLOCK_VISIBILITY_VIEWPORT_ENTRIES } from '../block-visibility/constants'; +import { getBlockVisibilityLabel } from '../block-visibility'; const { Badge } = unlock( componentsPrivateApis ); @@ -80,24 +79,7 @@ function ListViewBlockSelectButton( const images = useListViewImages( { clientId, isExpanded } ); // Determine visibility label from blockVisibility metadata - let visibilityLabel; - if ( blockVisibility === false ) { - // Hidden on all viewports - visibilityLabel = __( 'Block is hidden' ); - } else if ( blockVisibility?.viewport ) { - // Hidden on specific viewports - list them - const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( - ( [ key ] ) => blockVisibility.viewport?.[ key ] === false - ).map( ( [ , viewport ] ) => viewport.label ); - - if ( hiddenViewports.length > 0 ) { - visibilityLabel = sprintf( - /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ - __( 'Hidden on %s' ), - hiddenViewports.join( ', ' ) - ); - } - } + const visibilityLabel = getBlockVisibilityLabel( blockVisibility ); // The `href` attribute triggers the browser's native HTML drag operations. // When the link is dragged, the element's outerHTML is set in DataTransfer object as text/html. diff --git a/packages/block-editor/src/components/list-view/block.js b/packages/block-editor/src/components/list-view/block.js index 888e4c253d9c8f..0df5b3a57aac5a 100644 --- a/packages/block-editor/src/components/list-view/block.js +++ b/packages/block-editor/src/components/list-view/block.js @@ -25,7 +25,7 @@ import { memo, } from '@wordpress/element'; import { useDispatch, useSelect } from '@wordpress/data'; -import { __, sprintf } from '@wordpress/i18n'; +import { __ } from '@wordpress/i18n'; import { BACKSPACE, DELETE } from '@wordpress/keycodes'; import { isShallowEqual } from '@wordpress/is-shallow-equal'; import { __unstableUseShortcutEventMatch as useShortcutEventMatch } from '@wordpress/keyboard-shortcuts'; @@ -54,7 +54,7 @@ import { useBlockRename, BlockRenameModal } from '../block-rename'; import AriaReferencedText from './aria-referenced-text'; import { unlock } from '../../lock-unlock'; import usePasteStyles from '../use-paste-styles'; -import { BLOCK_VISIBILITY_VIEWPORT_ENTRIES } from '../block-visibility/constants'; +import { getBlockVisibilityLabel } from '../block-visibility'; function ListViewBlock( { block: { clientId }, @@ -142,38 +142,6 @@ function ListViewBlock( { ); const { canRename } = useBlockRename( blockName ); - // Determine label based on where block is hidden (not when/current viewport) - const blockVisibilityDescription = useMemo( () => { - const blockVisibility = block?.attributes?.metadata?.blockVisibility; - - // Not hidden at all - if ( ! blockVisibility && blockVisibility !== false ) { - return null; - } - - if ( blockVisibility === false ) { - // Hidden on all viewports - return __( 'Block is hidden' ); - } - - if ( blockVisibility?.viewport ) { - // Hidden on specific viewports - list them - const hiddenViewports = BLOCK_VISIBILITY_VIEWPORT_ENTRIES.filter( - ( [ key ] ) => blockVisibility.viewport?.[ key ] === false - ).map( ( [ , viewport ] ) => viewport.label ); - - if ( hiddenViewports.length > 0 ) { - return sprintf( - /* translators: %s: comma-separated list of viewport names (Desktop, Tablet, Mobile) */ - __( 'Block is hidden on %s' ), - hiddenViewports.join( ', ' ) - ); - } - } - - return null; - }, [ block?.attributes?.metadata?.blockVisibility ] ); - const showBlockActions = // When a block hides its toolbar it also hides the block settings menu, // since that menu is part of the toolbar in the editor canvas. @@ -560,6 +528,11 @@ function ListViewBlock( { isLocked ); + // Determine label based on where block is hidden (not when/current viewport) + const blockVisibilityDescription = getBlockVisibilityLabel( + block?.attributes?.metadata?.blockVisibility + ); + const hasSiblings = siblingBlockCount > 0; const hasRenderedMovers = showBlockMovers && hasSiblings; const moverCellClassName = clsx( From 9f450a96cf17b645cd19c65f45121e7f26654a5d Mon Sep 17 00:00:00 2001 From: Ramon Date: Tue, 17 Feb 2026 13:57:21 +1100 Subject: [PATCH 8/8] Update packages/block-editor/src/components/list-view/block-select-button.js --- .../src/components/list-view/block-select-button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/list-view/block-select-button.js b/packages/block-editor/src/components/list-view/block-select-button.js index f6d99ce5654a28..32df3b7458e4ee 100644 --- a/packages/block-editor/src/components/list-view/block-select-button.js +++ b/packages/block-editor/src/components/list-view/block-select-button.js @@ -163,7 +163,7 @@ function ListViewBlockSelectButton( ) ) } ) : null } - { visibilityLabel && ( + { !! visibilityLabel && (