diff --git a/packages/block-editor/src/components/block-types-list/index.js b/packages/block-editor/src/components/block-types-list/index.js
index 4709fa81fa61b9..6cff8bb6145588 100644
--- a/packages/block-editor/src/components/block-types-list/index.js
+++ b/packages/block-editor/src/components/block-types-list/index.js
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import { isEmpty } from 'lodash';
+
/**
* WordPress dependencies
*/
@@ -17,8 +22,36 @@ function BlockTypesList( { items, onSelect, onHover = () => {}, children } ) {
/* eslint-disable jsx-a11y/no-redundant-roles */
{ items && items.map( ( item ) => {
- const { patterns = [] } = item;
- const matchedPatterns = patterns.filter( ( { matched } ) => matched );
+ if ( ! isEmpty( item.patterns ) ) {
+ return item.patterns.map( ( pattern ) => {
+ const customizedItem = {
+ ...item,
+ initialAttributes: {
+ ...item.initialAttributes,
+ ...pattern.attributes,
+ },
+ innerBlocks: pattern.innerBlocks,
+ };
+ return (
+ {
+ onSelect( customizedItem );
+ onHover( null );
+ } }
+ onFocus={ () => onHover( customizedItem ) }
+ onMouseEnter={ () => onHover( customizedItem ) }
+ onMouseLeave={ () => onHover( null ) }
+ onBlur={ () => onHover( null ) }
+ isDisabled={ item.isDisabled }
+ title={ item.title }
+ patternName={ pattern.label }
+ />
+ );
+ } );
+ }
return (
{}, children } ) {
onBlur={ () => onHover( null ) }
isDisabled={ item.isDisabled }
title={ item.title }
- patterns={ matchedPatterns }
/>
);
} ) }
diff --git a/packages/block-editor/src/components/inserter-list-item/index.js b/packages/block-editor/src/components/inserter-list-item/index.js
index 55213af5f647d6..e34586f3f51841 100644
--- a/packages/block-editor/src/components/inserter-list-item/index.js
+++ b/packages/block-editor/src/components/inserter-list-item/index.js
@@ -19,7 +19,7 @@ function InserterListItem( {
isDisabled,
title,
className,
- patterns = [],
+ patternName,
...props
} ) {
const itemIconStyle = icon ? {
@@ -52,10 +52,8 @@ function InserterListItem( {
{ title }
- { patterns.map(
- ( { label, name } ) => (
- { label }
- )
+ { patternName && (
+ { patternName }
) }
diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js
index 45936b20db2e50..b9d57315268acb 100644
--- a/packages/block-editor/src/components/inserter/menu.js
+++ b/packages/block-editor/src/components/inserter/menu.js
@@ -58,6 +58,15 @@ const stopKeyPropagation = ( event ) => event.stopPropagation();
const getBlockNamespace = ( item ) => item.name.split( '/' )[ 0 ];
+// Copied over from the Columns block. It seems like it should become part of public API.
+const createBlocksFromInnerBlocksTemplate = ( innerBlocksTemplate ) => {
+ return map(
+ innerBlocksTemplate,
+ ( [ name, attributes, innerBlocks = [] ] ) =>
+ createBlock( name, attributes, createBlocksFromInnerBlocksTemplate( innerBlocks ) )
+ );
+};
+
export class InserterMenu extends Component {
constructor() {
super( ...arguments );
@@ -534,9 +543,13 @@ export default compose(
onSelect,
__experimentalSelectBlockOnInsert: selectBlockOnInsert,
} = ownProps;
- const { name, title, initialAttributes } = item;
+ const { name, title, initialAttributes, innerBlocks } = item;
const selectedBlock = getSelectedBlock();
- const insertedBlock = createBlock( name, initialAttributes );
+ const insertedBlock = createBlock(
+ name,
+ initialAttributes,
+ createBlocksFromInnerBlocksTemplate( innerBlocks )
+ );
if ( ! isAppender && selectedBlock && isUnmodifiedDefaultBlock( selectedBlock ) ) {
replaceBlocks( selectedBlock.clientId, insertedBlock );
diff --git a/packages/block-editor/src/components/inserter/search-items.js b/packages/block-editor/src/components/inserter/search-items.js
index d06bcab90ac1ed..b804dc9915cab1 100644
--- a/packages/block-editor/src/components/inserter/search-items.js
+++ b/packages/block-editor/src/components/inserter/search-items.js
@@ -7,6 +7,7 @@ import {
find,
get,
intersectionWith,
+ isEmpty,
words,
} from 'lodash';
@@ -102,22 +103,25 @@ export const searchItems = ( items, categories, collections, searchTerm ) => {
return unmatchedTerms.length === 0;
} ).map( ( item ) => {
- if ( ! item.patterns ) {
+ if ( isEmpty( item.patterns ) ) {
+ return item;
+ }
+
+ const matchedPatterns = item.patterns.filter( ( pattern ) => {
+ return intersectionWith(
+ normalizedSearchTerms,
+ normalizeSearchTerm( pattern.label ),
+ ( termToMatch, labelTerm ) => labelTerm.includes( termToMatch )
+ ).length > 0;
+ } );
+ // When no partterns matched, fallback to all patterns.
+ if ( isEmpty( matchedPatterns ) ) {
return item;
}
return {
...item,
- patterns: item.patterns.map( ( pattern ) => {
- return {
- ...pattern,
- matched: intersectionWith(
- normalizedSearchTerms,
- normalizeSearchTerm( pattern.label ),
- ( termToMatch, labelTerm ) => labelTerm.includes( termToMatch )
- ).length > 0,
- };
- } ),
+ patterns: matchedPatterns,
};
} );
};
diff --git a/packages/block-editor/src/components/inserter/test/search-items.js b/packages/block-editor/src/components/inserter/test/search-items.js
index 36686493600f2d..51ff69e5654ef9 100644
--- a/packages/block-editor/src/components/inserter/test/search-items.js
+++ b/packages/block-editor/src/components/inserter/test/search-items.js
@@ -84,12 +84,19 @@ describe( 'searchItems', () => {
);
} );
- it( 'should match words using the patterns and mark those matched which are scoped to inserter', () => {
+ it( 'should match words using also patterns and return all matched patterns', () => {
+ const filteredItems = searchItems( items, categories, collections, 'pattern' );
+
+ expect( filteredItems ).toHaveLength( 1 );
+ expect( filteredItems[ 0 ].patterns ).toHaveLength( 3 );
+ } );
+
+ it( 'should match words using also patterns and filter out unmatched patterns', () => {
const filteredItems = searchItems( items, categories, collections, 'patterns two three' );
expect( filteredItems ).toHaveLength( 1 );
- expect( filteredItems[ 0 ].patterns[ 0 ].matched ).toBe( false );
- expect( filteredItems[ 0 ].patterns[ 1 ].matched ).toBe( true );
- expect( filteredItems[ 0 ].patterns[ 2 ].matched ).toBe( true );
+ expect( filteredItems[ 0 ].patterns ).toHaveLength( 2 );
+ expect( filteredItems[ 0 ].patterns[ 0 ].label ).toBe( 'Pattern Two' );
+ expect( filteredItems[ 0 ].patterns[ 1 ].label ).toBe( 'Pattern Three' );
} );
} );