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();