diff --git a/packages/block-editor/src/components/block-switcher/index.js b/packages/block-editor/src/components/block-switcher/index.js
index dc3048bdda80b5..ef0d601c495c86 100644
--- a/packages/block-editor/src/components/block-switcher/index.js
+++ b/packages/block-editor/src/components/block-switcher/index.js
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
-import { castArray, uniq, truncate } from 'lodash';
+import { castArray, uniq } from 'lodash';
/**
* WordPress dependencies
@@ -17,6 +17,7 @@ import {
switchToBlockType,
store as blocksStore,
isReusableBlock,
+ isTemplatePart,
} from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import { stack } from '@wordpress/icons';
@@ -27,6 +28,7 @@ import { stack } from '@wordpress/icons';
import { store as blockEditorStore } from '../../store';
import useBlockDisplayInformation from '../use-block-display-information';
import BlockIcon from '../block-icon';
+import BlockTitle from '../block-title';
import BlockTransformationsMenu from './block-transformations-menu';
import BlockStylesMenu from './block-styles-menu';
@@ -40,11 +42,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
blockTitle,
} = useSelect(
( select ) => {
- const {
- getBlockRootClientId,
- getBlockTransformItems,
- __experimentalGetReusableBlockTitle,
- } = select( blockEditorStore );
+ const { getBlockRootClientId, getBlockTransformItems } = select(
+ blockEditorStore
+ );
const { getBlockStyles, getBlockType } = select( blocksStore );
const rootClientId = getBlockRootClientId(
@@ -55,14 +55,8 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
const styles =
_isSingleBlockSelected && getBlockStyles( firstBlockName );
let _icon;
- let reusableBlockTitle;
if ( _isSingleBlockSelected ) {
_icon = blockInformation?.icon; // Take into account active block variations.
- reusableBlockTitle =
- isReusableBlock( blocks[ 0 ] ) &&
- __experimentalGetReusableBlockTitle(
- blocks[ 0 ].attributes.ref
- );
} else {
const isSelectionOfSameType =
uniq( blocks.map( ( { name } ) => name ) ).length === 1;
@@ -80,14 +74,14 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
),
hasBlockStyles: !! styles?.length,
icon: _icon,
- blockTitle:
- reusableBlockTitle || getBlockType( firstBlockName ).title,
+ blockTitle: getBlockType( firstBlockName ).title,
};
},
[ clientIds, blocks, blockInformation?.icon ]
);
const isReusable = blocks.length === 1 && isReusableBlock( blocks[ 0 ] );
+ const isTemplate = blocks.length === 1 && isTemplatePart( blocks[ 0 ] );
const onTransform = ( name ) =>
replaceBlocks( clientIds, switchToBlockType( blocks, name ) );
@@ -139,11 +133,9 @@ export const BlockSwitcherDropdownMenu = ( { clientIds, blocks } ) => {
className="block-editor-block-switcher__toggle"
showColors
/>
- { isReusable && (
+ { ( isReusable || isTemplate ) && (
- { truncate( blockTitle, {
- length: 35,
- } ) }
+
) }
>
diff --git a/packages/block-editor/src/components/block-switcher/style.scss b/packages/block-editor/src/components/block-switcher/style.scss
index 55c978bb500d5a..a3d17760fcdca8 100644
--- a/packages/block-editor/src/components/block-switcher/style.scss
+++ b/packages/block-editor/src/components/block-switcher/style.scss
@@ -22,6 +22,15 @@
.block-editor-block-switcher__toggle-text {
margin-left: $grid-unit-10;
+
+ // Account for double label when show-text-buttons is set.
+ .show-icon-labels & {
+ display: none;
+ }
+}
+
+.show-icon-labels .block-editor-block-toolbar .block-editor-block-switcher .components-button.has-icon::after {
+ font-size: 14px;
}
// Indent the popover to match the button position.
diff --git a/packages/block-editor/src/components/block-title/index.js b/packages/block-editor/src/components/block-title/index.js
index e19125a6c95f5b..5a4b9a3e0e1219 100644
--- a/packages/block-editor/src/components/block-title/index.js
+++ b/packages/block-editor/src/components/block-title/index.js
@@ -65,16 +65,12 @@ export default function BlockTitle( { clientId } ) {
const blockInformation = useBlockDisplayInformation( clientId );
if ( ! name || ! blockInformation ) return null;
const blockType = getBlockType( name );
- const label = getBlockLabel( blockType, attributes );
- // Label will fallback to the title if no label is defined for the
- // current label context. We do not want "Paragraph: Paragraph".
- // If label is defined we prioritize it over possible possible
- // block variation match title.
+ const label = reusableBlockTitle || getBlockLabel( blockType, attributes );
+ // Label will fallback to the title if no label is defined for the current
+ // label context. If the label is defined we prioritize it over possible
+ // possible block variation title match.
if ( label !== blockType.title ) {
- return `${ blockType.title }: ${ truncate( label, { length: 15 } ) }`;
- }
- if ( reusableBlockTitle ) {
- return truncate( reusableBlockTitle, { length: 35 } );
+ return truncate( label, { length: 35 } );
}
return blockInformation.title;
}
diff --git a/packages/block-editor/src/components/block-title/test/index.js b/packages/block-editor/src/components/block-title/test/index.js
index 23af6288130e01..e2fb00937ba045 100644
--- a/packages/block-editor/src/components/block-title/test/index.js
+++ b/packages/block-editor/src/components/block-title/test/index.js
@@ -103,7 +103,7 @@ describe( 'BlockTitle', () => {
const wrapper = shallow( );
- expect( wrapper.text() ).toBe( 'Block With Label: Test Label' );
+ expect( wrapper.text() ).toBe( 'Test Label' );
} );
it( 'truncates the label if it is too long', () => {
@@ -116,8 +116,6 @@ describe( 'BlockTitle', () => {
);
- expect( wrapper.text() ).toBe(
- 'Block With Long Label: This is a lo...'
- );
+ expect( wrapper.text() ).toBe( 'This is a longer label than typi...' );
} );
} );
diff --git a/packages/blocks/README.md b/packages/blocks/README.md
index 2f3e282cab2ca4..f2347725ba74b9 100644
--- a/packages/blocks/README.md
+++ b/packages/blocks/README.md
@@ -534,6 +534,20 @@ _Returns_
- `boolean`: Whether the given block is a reusable block.
+# **isTemplatePart**
+
+Determines whether or not the given block is a template part. This is a
+special block type that allows composing a page template out of reusable
+design elements.
+
+_Parameters_
+
+- _blockOrType_ `Object`: Block or Block Type to test.
+
+_Returns_
+
+- `boolean`: Whether the given block is a template part.
+
# **isUnmodifiedDefaultBlock**
Determines whether the block is a default block
diff --git a/packages/blocks/src/api/index.js b/packages/blocks/src/api/index.js
index cedca941340778..afc632fe4942bc 100644
--- a/packages/blocks/src/api/index.js
+++ b/packages/blocks/src/api/index.js
@@ -123,6 +123,7 @@ export {
hasBlockSupport,
getBlockVariations,
isReusableBlock,
+ isTemplatePart,
getChildBlockNames,
hasChildBlocks,
hasChildBlocksWithInserterSupport,
diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js
index 8aa2f025410adf..6d327d3b0e2c88 100644
--- a/packages/blocks/src/api/registration.js
+++ b/packages/blocks/src/api/registration.js
@@ -474,6 +474,19 @@ export function isReusableBlock( blockOrType ) {
return blockOrType.name === 'core/block';
}
+/**
+ * Determines whether or not the given block is a template part. This is a
+ * special block type that allows composing a page template out of reusable
+ * design elements.
+ *
+ * @param {Object} blockOrType Block or Block Type to test.
+ *
+ * @return {boolean} Whether the given block is a template part.
+ */
+export function isTemplatePart( blockOrType ) {
+ return blockOrType.name === 'core/template-part';
+}
+
/**
* Returns an array with the child blocks of a given block.
*