Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fill quick inserter results with available variations if limit is set and items are less. #24481

Merged
merged 5 commits into from
Aug 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ export const withSingleVariationItem = {
],
};

export const withDefaultVariationItem = {
id: 'core/block-with-default-variation',
name: 'core/block-with-default-variation',
description: 'core description',
initialAttributes: {},
category: 'text',
variations: [
{
name: 'special',
title: 'Special',
isDefault: true,
},
],
};

export const withVariationsItem = {
id: 'core/block-with-variations',
name: 'core/block-with-variations',
Expand Down
44 changes: 44 additions & 0 deletions packages/block-editor/src/components/inserter/test/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,33 @@ import {
someOtherItem,
withVariationsItem,
withSingleVariationItem,
withDefaultVariationItem,
} from './fixtures';
import { includeVariationsInInserterItems } from '../utils';

describe( 'inserter utils', () => {
describe( 'includeVariationsInInserterItems', () => {
it( 'should let a block type be replaced with the default variation', () => {
// The base block type is replaced with the default variation
expect(
includeVariationsInInserterItems( [ withDefaultVariationItem ] )
).toEqual( [
expect.objectContaining( {
id: 'core/block-with-default-variation-special',
} ),
] );
// The base block type is supplemented by non-default variations
expect(
includeVariationsInInserterItems( [ withSingleVariationItem ] )
).toEqual( [
expect.objectContaining( {
id: 'core/embed',
} ),
expect.objectContaining( {
id: 'core/embed-youtube',
} ),
] );
} );
it( 'should return items if limit is equal to items length', () => {
const items = [ moreItem, paragraphItem, someOtherItem ];
const res = includeVariationsInInserterItems( items, 3 );
Expand All @@ -27,6 +49,28 @@ describe( 'inserter utils', () => {
const res = includeVariationsInInserterItems( items, 2 );
expect( res ).toEqual( [ moreItem, paragraphItem ] );
} );
it( 'should fill the items with variations, if limit is set and items are fewer than limit and variations exist', () => {
const items = [ moreItem, paragraphItem, withVariationsItem ];
const res = includeVariationsInInserterItems( items, 5 );
expect( res.length ).toEqual( 5 );
expect( res ).toEqual( [
...items,
expect.objectContaining( {
id: 'core/block-with-variations-variation-one',
title: 'Variation One',
} ),
expect.objectContaining( {
id: 'core/block-with-variations-variation-two',
title: 'Variation Two',
} ),
] );
} );
it( 'should return the items, if limit is set and items are fewer than limit and variations do NOT exist', () => {
const items = [ moreItem, paragraphItem, someOtherItem ];
const res = includeVariationsInInserterItems( items, 4 );
expect( res.length ).toEqual( 3 );
expect( res ).toEqual( items );
} );
it( 'should return proper result if no limit provided and block variations do NOT exist', () => {
const items = [ moreItem, paragraphItem, someOtherItem ];
const res = includeVariationsInInserterItems( items );
Expand Down
42 changes: 22 additions & 20 deletions packages/block-editor/src/components/inserter/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,30 @@ const getItemFromVariation = ( item ) => ( variation ) => ( {
* @return {Array} Normalized inserter items.
*/
export function includeVariationsInInserterItems( items, limit = Infinity ) {
if ( items.length >= limit ) {
// No need to iterate for variations
return items.slice( 0, limit );
}
// Show all available blocks with variations
return items.reduce( ( result, item ) => {
const { variations = [] } = item;
const hasDefaultVariation = variations.some(
( { isDefault } ) => isDefault
);
// Exclude any block type item that is to be replaced by a default
// variation.
const filteredItems = items.filter(
( { variations = [] } ) =>
! variations.some( ( { isDefault } ) => isDefault )
);

// If there is no default inserter variation provided,
// then default block type is displayed.
if ( ! hasDefaultVariation ) {
result.push( item );
}
// Fill `variationsToAdd` until there are as many items in total as
// `limit`.
const variationsToAdd = [];
if ( filteredItems.length < limit ) {
// Show all available blocks with variations
for ( const item of items ) {
if ( filteredItems.length + variationsToAdd.length >= limit ) {
break;
}

if ( variations.length ) {
const variationMapper = getItemFromVariation( item );
result.push( ...variations.map( variationMapper ) );
const { variations = [] } = item;
if ( variations.length ) {
const variationMapper = getItemFromVariation( item );
variationsToAdd.push( ...variations.map( variationMapper ) );
}
}
}

return result;
}, [] );
return [ ...filteredItems, ...variationsToAdd ].slice( 0, limit );
}