diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 00c50b76d1e7a..61501dae210e8 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1618,25 +1618,32 @@ export const getInserterItems = createSelector( blockVariations.push( ...variations.map( variationMapper ) ); } } - // 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 groupByType = ( blocks, block ) => { + const { core, noncore } = blocks; + const type = block.name.startsWith( 'core/' ) ? core : noncore; + + type.push( block ); + return blocks; + }; + const items = visibleBlockTypeInserterItems.reduce( groupByType, { + core: [], + noncore: [], + } ); + const variations = blockVariations.reduce( groupByType, { + core: [], + noncore: [], + } ); const sortedBlockTypes = [ - ...visibleBlockTypeInserterItems, - ...blockVariations, - ].sort( prioritizeCoreBlocks ); + ...items.core, + ...variations.core, + ...items.noncore, + ...variations.noncore, + ]; return [ ...sortedBlockTypes, ...reusableBlockInserterItems ]; }, ( state, rootClientId ) => [ diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index 0e67cc0f1d551..1d96c678b2b48 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -3725,6 +3725,13 @@ describe( 'getInserterItems with core blocks prioritization', () => { title: 'Another Plugin Block B', icon: 'test', } ); + registerBlockType( 'plugin/block-c-with-variations', { + save() {}, + category: 'text', + title: 'Plugin Block C with variations', + icon: 'test', + variations: [ { name: 'variation-a' }, { name: 'variation-b' } ], + } ); registerBlockType( 'core/block', { save() {}, category: 'text', @@ -3737,13 +3744,23 @@ describe( 'getInserterItems with core blocks prioritization', () => { icon: 'test', keywords: [ 'testing' ], } ); + registerBlockType( 'core/test-block-with-variations', { + save() {}, + category: 'text', + title: 'Core Block C with variations', + icon: 'test', + keywords: [ 'testing' ], + variations: [ { name: 'variation-a' }, { name: 'variation-b' } ], + } ); } ); afterEach( () => { [ 'plugin/block-a', 'another-plugin/block-b', + 'plugin/block-c-with-variations', 'core/block', 'core/test-block-a', + 'core/test-block-with-variations', ].forEach( unregisterBlockType ); } ); it( 'should prioritize core blocks by sorting them at the top of the returned list', () => { @@ -3763,10 +3780,16 @@ describe( 'getInserterItems with core blocks prioritization', () => { const expectedResult = [ 'core/block', 'core/test-block-a', + 'core/test-block-with-variations', + 'core/test-block-with-variations/variation-a', + 'core/test-block-with-variations/variation-b', 'plugin/block-a', 'another-plugin/block-b', + 'plugin/block-c-with-variations', + 'plugin/block-c-with-variations/variation-a', + 'plugin/block-c-with-variations/variation-b', ]; - expect( items.map( ( { name } ) => name ) ).toEqual( expectedResult ); + expect( items.map( ( { id } ) => id ) ).toEqual( expectedResult ); } ); } );