diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 6f7b087c6faacc..305c32f9d5d7df 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -246,6 +246,7 @@ _Parameters_ - _props_ `Object`: - _props.clientId_ `string`: Client ID of block. - _props.maximumLength_ `number|undefined`: The maximum length that the block title string may be before truncated. +- _props.context_ `string|undefined`: The context to pass to `getBlockLabel`. _Returns_ diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js index cc80dc863c7986..2d0571397a8eaa 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.js @@ -125,7 +125,10 @@ export function BlockSettingsDropdown( { [ __experimentalSelectBlock ] ); - const blockTitle = useBlockDisplayTitle( firstBlockClientId, 25 ); + const blockTitle = useBlockDisplayTitle( { + clientId: firstBlockClientId, + maximumLength: 25, + } ); const updateSelectionAfterRemove = useCallback( __experimentalSelectBlock diff --git a/packages/block-editor/src/components/block-title/index.js b/packages/block-editor/src/components/block-title/index.js index 2849c82f332bdc..4075171c87e476 100644 --- a/packages/block-editor/src/components/block-title/index.js +++ b/packages/block-editor/src/components/block-title/index.js @@ -17,9 +17,10 @@ import useBlockDisplayTitle from './use-block-display-title'; * @param {Object} props * @param {string} props.clientId Client ID of block. * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. + * @param {string|undefined} props.context The context to pass to `getBlockLabel`. * * @return {JSX.Element} Block title. */ -export default function BlockTitle( { clientId, maximumLength } ) { - return useBlockDisplayTitle( clientId, maximumLength ); +export default function BlockTitle( { clientId, maximumLength, context } ) { + return useBlockDisplayTitle( { clientId, maximumLength, context } ); } diff --git a/packages/block-editor/src/components/block-title/use-block-display-title.js b/packages/block-editor/src/components/block-title/use-block-display-title.js index ab5aed4dbb84e8..be1e26319d671c 100644 --- a/packages/block-editor/src/components/block-title/use-block-display-title.js +++ b/packages/block-editor/src/components/block-title/use-block-display-title.js @@ -21,14 +21,20 @@ import { store as blockEditorStore } from '../../store'; * @example * * ```js - * useBlockDisplayTitle( 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', 17 ); + * useBlockDisplayTitle( { clientId: 'afd1cb17-2c08-4e7a-91be-007ba7ddc3a1', maximumLength: 17 } ); * ``` * - * @param {string} clientId Client ID of block. - * @param {number|undefined} maximumLength The maximum length that the block title string may be before truncated. + * @param {Object} props + * @param {string} props.clientId Client ID of block. + * @param {number|undefined} props.maximumLength The maximum length that the block title string may be before truncated. + * @param {string|undefined} props.context The context to pass to `getBlockLabel`. * @return {?string} Block title. */ -export default function useBlockDisplayTitle( clientId, maximumLength ) { +export default function useBlockDisplayTitle( { + clientId, + maximumLength, + context, +} ) { const { attributes, name, reusableBlockTitle } = useSelect( ( select ) => { if ( ! clientId ) { @@ -63,7 +69,7 @@ export default function useBlockDisplayTitle( clientId, maximumLength ) { } const blockType = getBlockType( name ); const blockLabel = blockType - ? getBlockLabel( blockType, attributes ) + ? getBlockLabel( blockType, attributes, context ) : null; const label = reusableBlockTitle || blockLabel; 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 f6eb82be503784..661bbec4dbfc46 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 @@ -6,7 +6,11 @@ import classnames from 'classnames'; /** * WordPress dependencies */ -import { Button } from '@wordpress/components'; +import { + Button, + __experimentalHStack as HStack, + __experimentalTruncate as Truncate, +} from '@wordpress/components'; import { forwardRef } from '@wordpress/element'; import { Icon, lock } from '@wordpress/icons'; import { SPACE, ENTER } from '@wordpress/keycodes'; @@ -16,7 +20,7 @@ import { SPACE, ENTER } from '@wordpress/keycodes'; */ import BlockIcon from '../block-icon'; import useBlockDisplayInformation from '../use-block-display-information'; -import BlockTitle from '../block-title'; +import useBlockDisplayTitle from '../block-title/use-block-display-title'; import ListViewExpander from './expander'; import { useBlockLock } from '../block-lock'; @@ -35,6 +39,10 @@ function ListViewBlockSelectButton( ref ) { const blockInformation = useBlockDisplayInformation( clientId ); + const blockTitle = useBlockDisplayTitle( { + clientId, + context: 'list-view', + } ); const { isLocked } = useBlockLock( clientId ); // The `href` attribute triggers the browser's native HTML drag operations. @@ -72,19 +80,26 @@ function ListViewBlockSelectButton( > - - - - { blockInformation?.anchor && ( - - { blockInformation.anchor } + + + { blockTitle } - ) } - { isLocked && ( - - - - ) } + { blockInformation?.anchor && ( + + { blockInformation.anchor } + + ) } + { isLocked && ( + + + + ) } + ); diff --git a/packages/block-editor/src/components/list-view/style.scss b/packages/block-editor/src/components/list-view/style.scss index a4efefeafbd992..4fce1136bdbd5a 100644 --- a/packages/block-editor/src/components/list-view/style.scss +++ b/packages/block-editor/src/components/list-view/style.scss @@ -97,7 +97,7 @@ align-items: center; width: 100%; height: auto; - padding: ($grid-unit-15 * 0.5) $grid-unit-15 ($grid-unit-15 * 0.5) 0; + padding: ($grid-unit-15 * 0.5) $grid-unit-05 ($grid-unit-15 * 0.5) 0; text-align: left; color: $gray-900; border-radius: $radius-block-ui; @@ -207,7 +207,7 @@ } .block-editor-list-view-block__menu-cell { - padding-right: 5px; + padding-right: $grid-unit-05; .components-button.has-icon { height: 24px; @@ -297,13 +297,27 @@ } } + .block-editor-list-view-block-select-button__label-wrapper { + min-width: 120px; + } + + .block-editor-list-view-block-select-button__title { + flex: 1; + position: relative; + + .components-truncate { + position: absolute; + width: 100%; + transform: translateY(-50%); + } + } + .block-editor-list-view-block-select-button__anchor { background: rgba($black, 0.1); border-radius: $radius-block-ui; display: inline-block; padding: 2px 6px; - margin: 0 $grid-unit-10; - max-width: 120px; + max-width: min(100px, 40%); overflow: hidden; text-overflow: ellipsis; } diff --git a/packages/block-library/src/heading/index.js b/packages/block-library/src/heading/index.js index 989812cd46c89b..e829a7ae15108e 100644 --- a/packages/block-library/src/heading/index.js +++ b/packages/block-library/src/heading/index.js @@ -31,9 +31,15 @@ export const settings = { }, }, __experimentalLabel( attributes, { context } ) { - if ( context === 'accessibility' ) { - const { content, level } = attributes; + const { content, level } = attributes; + + // In the list view, use the block's content as the label. + // If the content is empty, fall back to the default label. + if ( context === 'list-view' && content ) { + return content; + } + if ( context === 'accessibility' ) { return isEmpty( content ) ? sprintf( /* translators: accessibility text. %s: heading level. */ diff --git a/packages/e2e-test-utils/src/get-list-view-blocks.js b/packages/e2e-test-utils/src/get-list-view-blocks.js index af1d46ad5273f7..8b52953b58290f 100644 --- a/packages/e2e-test-utils/src/get-list-view-blocks.js +++ b/packages/e2e-test-utils/src/get-list-view-blocks.js @@ -6,6 +6,6 @@ */ export async function getListViewBlocks( blockLabel ) { return page.$x( - `//table[contains(@aria-label,'Block navigation structure')]//a[span[text()='${ blockLabel }']]` + `//table[contains(@aria-label,'Block navigation structure')]//a[.//span[text()='${ blockLabel }']]` ); } diff --git a/packages/e2e-tests/specs/editor/blocks/gallery.test.js b/packages/e2e-tests/specs/editor/blocks/gallery.test.js index 0ca66f2b977584..8ffe087f2668a9 100644 --- a/packages/e2e-tests/specs/editor/blocks/gallery.test.js +++ b/packages/e2e-tests/specs/editor/blocks/gallery.test.js @@ -103,7 +103,7 @@ describe( 'Gallery', () => { // This xpath selects the anchor node for the block which has a child span which contains the text // label of the block and then selects the expander span for that node. const galleryExpander = await page.waitForXPath( - `//a[span[text()='Gallery']]/span[contains(@class, 'block-editor-list-view__expander')]` + `//a[.//span[text()='Gallery']]/span[contains(@class, 'block-editor-list-view__expander')]` ); await galleryExpander.click(); diff --git a/packages/e2e-tests/specs/editor/blocks/navigation.test.js b/packages/e2e-tests/specs/editor/blocks/navigation.test.js index ee75374afdf53d..0f69d83ed3cc34 100644 --- a/packages/e2e-tests/specs/editor/blocks/navigation.test.js +++ b/packages/e2e-tests/specs/editor/blocks/navigation.test.js @@ -1047,7 +1047,7 @@ Expected mock function not to be called but it was called with: ["POST", "http:/ await openListView(); const navExpander = await page.waitForXPath( - `//a[span[text()='Navigation']]/span[contains(@class, 'block-editor-list-view__expander')]` + `//a[.//span[text()='Navigation']]/span[contains(@class, 'block-editor-list-view__expander')]` ); await navExpander.click();