Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -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';
40 changes: 40 additions & 0 deletions packages/block-editor/src/components/block-visibility/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* WordPress dependencies
*/
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
Expand Down Expand Up @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import clsx from 'clsx';
import {
__experimentalHStack as HStack,
__experimentalTruncate as Truncate,
Tooltip,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { forwardRef } from '@wordpress/element';
Expand All @@ -33,6 +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 { getBlockVisibilityLabel } from '../block-visibility';

const { Badge } = unlock( componentsPrivateApis );

Expand Down Expand Up @@ -60,16 +62,13 @@ function ListViewBlockSelectButton(
context: 'list-view',
} );
const { isLocked } = useBlockLock( clientId );
const { isBlockHidden, hasPatternName } = 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:
!! getBlockAttributes( clientId )?.metadata?.patternName,
hasPatternName: !! attributes?.metadata?.patternName,
blockVisibility: attributes?.metadata?.blockVisibility,
};
},
[ clientId ]
Expand All @@ -79,6 +78,9 @@ function ListViewBlockSelectButton(
const isSticky = blockInformation?.positionType === 'sticky';
const images = useListViewImages( { clientId, isExpanded } );

// Determine visibility label from blockVisibility metadata
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.
// We need to clear any HTML drag data to prevent `pasteHandler` from firing
Expand Down Expand Up @@ -161,10 +163,15 @@ function ListViewBlockSelectButton(
) ) }
</span>
) : null }
{ isBlockHidden && (
<span className="block-editor-list-view-block-select-button__block-visibility">
<Icon icon={ unseen } />
</span>
{ !! visibilityLabel && (
<Tooltip text={ visibilityLabel }>
<span
className="block-editor-list-view-block-select-button__block-visibility"
aria-hidden="true"
>
<Icon icon={ unseen } />
</span>
</Tooltip>
) }
{ shouldShowLockIcon && (
<span className="block-editor-list-view-block-select-button__lock">
Expand Down
68 changes: 21 additions & 47 deletions packages/block-editor/src/components/list-view/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 { getBlockVisibilityLabel } from '../block-visibility';

function ListViewBlock( {
block: { clientId },
Expand Down Expand Up @@ -127,51 +125,22 @@ 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 blockVisibilityDescription = useMemo( () => {
if ( isBlockCurrentlyHidden ) {
if ( block?.attributes?.metadata?.blockVisibility === false ) {
return __( 'Block is hidden' );
}
return sprintf(
/* translators: %s: viewport name (Desktop, Tablet, Mobile) */
__( 'Block is hidden on %s' ),
BLOCK_VISIBILITY_VIEWPORTS[ currentViewport ]?.label ||
currentViewport
);
}
return null;
}, [
isBlockCurrentlyHidden,
block?.attributes?.metadata?.blockVisibility,
currentViewport,
] );

const showBlockActions =
// When a block hides its toolbar it also hides the block settings menu,
Expand Down Expand Up @@ -559,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(
Expand Down
Loading