Skip to content

Commit

Permalink
Introduce scopes for block patterns
Browse files Browse the repository at this point in the history
  • Loading branch information
gziolo committed Jan 15, 2020
1 parent c96548f commit a9e5124
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 46 deletions.
40 changes: 22 additions & 18 deletions packages/block-editor/src/components/block-types-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,28 @@ function BlockTypesList( { items, onSelect, onHover = () => {}, children } ) {
*/
/* eslint-disable jsx-a11y/no-redundant-roles */
<ul role="list" className="block-editor-block-types-list">
{ items && items.map( ( item ) =>
<InserterListItem
key={ item.id }
className={ getBlockMenuDefaultClassName( item.id ) }
icon={ item.icon }
onClick={ () => {
onSelect( item );
onHover( null );
} }
onFocus={ () => onHover( item ) }
onMouseEnter={ () => onHover( item ) }
onMouseLeave={ () => onHover( null ) }
onBlur={ () => onHover( null ) }
isDisabled={ item.isDisabled }
title={ item.title }
patterns={ item.patterns }
/>
) }
{ items && items.map( ( item ) => {
const { patterns = [] } = item;
const matchedPatterns = patterns.filter( ( { matched } ) => matched );
return (
<InserterListItem
key={ item.id }
className={ getBlockMenuDefaultClassName( item.id ) }
icon={ item.icon }
onClick={ () => {
onSelect( item );
onHover( null );
} }
onFocus={ () => onHover( item ) }
onMouseEnter={ () => onHover( item ) }
onMouseLeave={ () => onHover( null ) }
onBlur={ () => onHover( null ) }
isDisabled={ item.isDisabled }
title={ item.title }
patterns={ matchedPatterns }
/>
);
} ) }
{ children }
</ul>
/* eslint-enable jsx-a11y/no-redundant-roles */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function InserterListItem( {
isDisabled,
title,
className,
patterns,
patterns = [],
...props
} ) {
const itemIconStyle = icon ? {
Expand Down Expand Up @@ -52,7 +52,7 @@ function InserterListItem( {
<span className="block-editor-block-types-list__item-title">
{ title }
</span>
{ patterns.filter( ( { matched } ) => matched ).map(
{ patterns.map(
( { label, name } ) => (
<em style={ { padding: '5px' } } key={ name }>{ label }</em>
)
Expand Down
15 changes: 8 additions & 7 deletions packages/block-editor/src/components/inserter/search-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
differenceWith,
find,
get,
intersection,
intersectionWith,
words,
} from 'lodash';

Expand Down Expand Up @@ -53,15 +53,15 @@ const removeMatchingTerms = ( unmatchedTerms, unprocessedTerms ) => {
* @return {Array} Filtered item list.
*/
export const searchItems = ( items, categories, collections, searchTerm ) => {
const normalizedTerms = normalizeSearchTerm( searchTerm );
const normalizedSearchTerms = normalizeSearchTerm( searchTerm );

if ( normalizedTerms.length === 0 ) {
if ( normalizedSearchTerms.length === 0 ) {
return items;
}

return items.filter( ( { name, title, category, keywords = [], patterns = [] } ) => {
let unmatchedTerms = removeMatchingTerms(
normalizedTerms,
normalizedSearchTerms,
title
);

Expand Down Expand Up @@ -111,9 +111,10 @@ export const searchItems = ( items, categories, collections, searchTerm ) => {
patterns: item.patterns.map( ( pattern ) => {
return {
...pattern,
matched: intersection(
normalizedTerms,
normalizeSearchTerm( pattern.label )
matched: intersectionWith(
normalizedSearchTerms,
normalizeSearchTerm( pattern.label ),
( termToMatch, labelTerm ) => labelTerm.includes( termToMatch )
).length > 0,
};
} ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ describe( 'searchItems', () => {
);
} );

it( 'should match words using the patterns and mark those matched', () => {
it( 'should match words using the patterns and mark those matched which are scoped to inserter', () => {
const filteredItems = searchItems( items, categories, collections, 'patterns two three' );

expect( filteredItems ).toHaveLength( 1 );
Expand Down
5 changes: 4 additions & 1 deletion packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,9 @@ export const getInserterItems = createSelector(

const isContextual = isArray( blockType.parent );
const { time, count = 0 } = getInsertUsage( state, id ) || {};
const inserterPatterns = blockType.patterns.filter(
( { scope } ) => ! scope || scope.includes( 'inserter' )
);

return {
id,
Expand All @@ -1264,7 +1267,7 @@ export const getInserterItems = createSelector(
icon: blockType.icon,
category: blockType.category,
keywords: blockType.keywords,
patterns: blockType.patterns,
patterns: inserterPatterns,
isDisabled,
utility: calculateUtility( blockType.category, count, isContextual ),
frecency: calculateFrecency( time, count ),
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/columns/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ const ColumnsEdit = ( props ) => {

return {
blockType: getBlockType( name ),
defaultPattern: __experimentalGetDefaultBlockPattern( name ),
defaultPattern: __experimentalGetDefaultBlockPattern( name, 'block' ),
hasInnerBlocks: select( 'core/block-editor' ).getBlocks( clientId ).length > 0,
patterns: __experimentalGetBlockPatterns( name ),
patterns: __experimentalGetBlockPatterns( name, 'block' ),
};
}, [ clientId, name ] );

Expand Down
5 changes: 5 additions & 0 deletions packages/block-library/src/columns/patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const patterns = [
[ 'core/column' ],
[ 'core/column' ],
],
scope: [ 'block' ],
},
{
name: 'two-columns-one-third-two-thirds',
Expand All @@ -28,6 +29,7 @@ const patterns = [
[ 'core/column', { width: 33.33 } ],
[ 'core/column', { width: 66.66 } ],
],
scope: [ 'block' ],
},
{
name: 'two-columns-two-thirds-one-third',
Expand All @@ -37,6 +39,7 @@ const patterns = [
[ 'core/column', { width: 66.66 } ],
[ 'core/column', { width: 33.33 } ],
],
scope: [ 'block' ],
},
{
name: 'three-columns-equal',
Expand All @@ -47,6 +50,7 @@ const patterns = [
[ 'core/column' ],
[ 'core/column' ],
],
scope: [ 'block' ],
},
{
name: 'three-columns-wider-center',
Expand All @@ -57,6 +61,7 @@ const patterns = [
[ 'core/column', { width: 50 } ],
[ 'core/column', { width: 25 } ],
],
scope: [ 'block' ],
},
];

Expand Down
23 changes: 16 additions & 7 deletions packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,27 @@ import { DEPRECATED_ENTRY_KEYS } from './constants';
* @typedef {(WPBlockTypeIconDescriptor|WPBlockTypeIconRender)} WPBlockTypeIcon
*/

/**
* Named block pattern scopes.
*
* @typedef {'block'|'inserter'} WPBlockPatternScope
*/

/**
* An object describing a pattern defined for the block type.
*
* @typedef {Object} WPBlockPattern
*
* @property {string} name The unique and machine-readable name.
* @property {string} label A human-readable label.
* @property {WPIcon} [icon] An icon helping to visualize the pattern.
* @property {boolean} [isDefault] Indicates whether the current pattern is the default one.
* Defaults to `false`.
* @property {Object} [attributes] Values which override block attributes.
* @property {Array[]} [innerBlocks] Initial configuration of nested blocks.
* @property {string} name The unique and machine-readable name.
* @property {string} label A human-readable label.
* @property {WPIcon} [icon] An icon helping to visualize the pattern.
* @property {boolean} [isDefault] Indicates whether the current pattern is
* the default one. Defaults to `false`.
* @property {Object} [attributes] Values which override block attributes.
* @property {Array[]} [innerBlocks] Initial configuration of nested blocks.
* @property {WPBlockPatternScope[]} [scope] The list of scopes where the pattern
* is applicable. When not provided, it
* assumes all available scopes.
*/

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/blocks/src/api/test/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ describe( 'blocks', () => {
},
attributes: {},
keywords: [],
patterns: [],
},
] );
const oldBlock = unregisterBlockType( 'core/test-block' );
Expand Down Expand Up @@ -606,6 +607,7 @@ describe( 'blocks', () => {
},
attributes: {},
keywords: [],
patterns: [],
},
{
name: 'core/test-block-with-settings',
Expand All @@ -618,6 +620,7 @@ describe( 'blocks', () => {
},
attributes: {},
keywords: [],
patterns: [],
},
] );
} );
Expand Down
26 changes: 18 additions & 8 deletions packages/blocks/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
some,
} from 'lodash';

/** @typedef {import('../api/registration').WPBlockPatternScope} WPBlockPatternScope */

/**
* Given a block name or block type object, returns the corresponding
* normalized block type object.
Expand Down Expand Up @@ -78,13 +80,20 @@ export function getBlockStyles( state, name ) {
/**
* Returns block patterns by block name.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {WPBlockPatternScope} [scope] Block pattern scope name.
*
* @return {(WPBlockPattern[]|void)} Block patterns.
*/
export function __experimentalGetBlockPatterns( state, blockName ) {
return state.blockPatterns[ blockName ];
export function __experimentalGetBlockPatterns( state, blockName, scope ) {
const patterns = state.blockPatterns[ blockName ];
if ( ! patterns || ! scope ) {
return patterns;
}
return patterns.filter( ( pattern ) => {
return ! pattern.scope || pattern.scope.includes( scope );
} );
}

/**
Expand All @@ -93,13 +102,14 @@ export function __experimentalGetBlockPatterns( state, blockName ) {
* the last added item is picked. This simplifies registering overrides.
* When there is no default pattern set, it returns the first item.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {Object} state Data state.
* @param {string} blockName Block type name.
* @param {WPBlockPatternScope} [scope] Block pattern scope name.
*
* @return {?WPBlockPattern} The default block pattern.
*/
export function __experimentalGetDefaultBlockPattern( state, blockName ) {
const patterns = __experimentalGetBlockPatterns( state, blockName );
export function __experimentalGetDefaultBlockPattern( state, blockName, scope ) {
const patterns = __experimentalGetBlockPatterns( state, blockName, scope );

return findLast( patterns, 'isDefault' ) || first( patterns );
}
Expand Down

0 comments on commit a9e5124

Please sign in to comment.