Skip to content

Commit

Permalink
Prioritize core blocks in the inserter (#28945)
Browse files Browse the repository at this point in the history
* prioritze core blocks in the inserter context

* prioritize core blocks in the selector
  • Loading branch information
ntsekouras authored Feb 17, 2021
1 parent 9e28157 commit eaee075
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
12 changes: 2 additions & 10 deletions packages/block-editor/src/components/inserter/block-types-tab.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { map, findIndex, flow, sortBy, groupBy, orderBy } from 'lodash';
import { map, flow, groupBy, orderBy } from 'lodash';

/**
* WordPress dependencies
Expand Down Expand Up @@ -43,22 +43,14 @@ export function BlockTypesTab( {
}, [ items ] );

const itemsPerCategory = useMemo( () => {
const getCategoryIndex = ( item ) => {
return findIndex(
categories,
( category ) => category.slug === item.category
);
};

return flow(
( itemList ) =>
itemList.filter(
( item ) => item.category && item.category !== 'reusable'
),
( itemList ) => sortBy( itemList, getCategoryIndex ),
( itemList ) => groupBy( itemList, 'category' )
)( items );
}, [ items, categories ] );
}, [ items ] );

const itemsPerCollection = useMemo( () => {
// Create a new Object to avoid mutating collection.
Expand Down
22 changes: 18 additions & 4 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1600,12 +1600,26 @@ export const getInserterItems = createSelector(
blockVariations.push( ...variations.map( variationMapper ) );
}
}

return [
// Prioritize core blocks's display in inserter.
const prioritizeCoreBlocks = ( a, b ) => {
const coreBlockNamePrefix = 'core/';
const firstIsCoreBlock = a.name.startsWith( coreBlockNamePrefix );
const secondIsCoreBlock = b.name.startsWith( coreBlockNamePrefix );
if ( firstIsCoreBlock && secondIsCoreBlock ) {
return 0;
}
return firstIsCoreBlock && ! secondIsCoreBlock ? -1 : 1;
};
// Ensure core blocks are prioritized in the returned results,
// because third party blocks can be registered earlier than
// the core blocks (usually by using the `init` action),
// thus affecting the display order.
// We don't sort reusable blocks as they are handled differently.
const sortedBlockTypes = [
...visibleBlockTypeInserterItems,
...blockVariations,
...reusableBlockInserterItems,
];
].sort( prioritizeCoreBlocks );
return [ ...sortedBlockTypes, ...reusableBlockInserterItems ];
},
( state, rootClientId ) => [
state.blockListSettings[ rootClientId ],
Expand Down
64 changes: 64 additions & 0 deletions packages/block-editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3423,3 +3423,67 @@ describe( '__experimentalGetParsedReusableBlock', () => {
);
} );
} );

describe( 'getInserterItems with core blocks prioritization', () => {
// This test is in a seperate `describe` because all other tests register
// some test `core` blocks and interfere with the purpose of the specific test.
// This tests the functionality to ensure core blocks are prioritized in the
// returned results, because third party blocks can be registered earlier than
// the core blocks (usually by using the `init` action), thus affecting the display order.
beforeEach( () => {
registerBlockType( 'plugin/block-a', {
save() {},
category: 'text',
title: 'Plugin Block A',
icon: 'test',
} );
registerBlockType( 'another-plugin/block-b', {
save() {},
category: 'text',
title: 'Another Plugin Block B',
icon: 'test',
} );
registerBlockType( 'core/block', {
save() {},
category: 'text',
title: 'Core Block A',
} );
registerBlockType( 'core/test-block-a', {
save: ( props ) => props.attributes.text,
category: 'design',
title: 'Core Block B',
icon: 'test',
keywords: [ 'testing' ],
} );
} );
afterEach( () => {
[
'plugin/block-a',
'another-plugin/block-b',
'core/block',
'core/test-block-a',
].forEach( unregisterBlockType );
} );
it( 'should prioritize core blocks by sorting them at the top of the returned list', () => {
const state = {
blocks: {
byClientId: {},
attributes: {},
order: {},
parents: {},
cache: {},
},
settings: {},
preferences: {},
blockListSettings: {},
};
const items = getInserterItems( state );
const expectedResult = [
'core/block',
'core/test-block-a',
'plugin/block-a',
'another-plugin/block-b',
];
expect( items.map( ( { name } ) => name ) ).toEqual( expectedResult );
} );
} );

0 comments on commit eaee075

Please sign in to comment.