Skip to content

Commit

Permalink
Inserter: show all blocks (alternative) (WordPress#62169)
Browse files Browse the repository at this point in the history
* Inserter: show all block

* Fix parents

* Use section root as fallback

* Remove heading, remove reusable blocks

* Add private selector option

* Fix quick inserter

* Fix appender inserter

* Fix most used, fix quick inserter

* Fix widgets page

* Fix e2e tests

Co-authored-by: ellatrix <[email protected]>
Co-authored-by: draganescu <[email protected]>
Co-authored-by: jeryj <[email protected]>
Co-authored-by: jasmussen <[email protected]>
Co-authored-by: jameskoster <[email protected]>
Co-authored-by: youknowriad <[email protected]>
Co-authored-by: richtabor <[email protected]>
Co-authored-by: SaxonF <[email protected]>
Co-authored-by: annezazu <[email protected]>
  • Loading branch information
10 people authored and patil-vipul committed Jun 17, 2024
1 parent ea6cefa commit 2367f55
Show file tree
Hide file tree
Showing 11 changed files with 303 additions and 115 deletions.
198 changes: 120 additions & 78 deletions packages/block-editor/src/components/inserter/block-types-tab.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import { __, _x } from '@wordpress/i18n';
import { useMemo, useEffect, forwardRef } from '@wordpress/element';
import { pipe, useAsyncList } from '@wordpress/compose';
import { useAsyncList } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -27,15 +27,15 @@ const MAX_SUGGESTED_ITEMS = 6;
*/
const EMPTY_ARRAY = [];

export function BlockTypesTab(
{ rootClientId, onInsert, onHover, showMostUsedBlocks },
ref
) {
const [ items, categories, collections, onSelectItem ] = useBlockTypesState(
rootClientId,
onInsert
);

export function BlockTypesTabPanel( {
items,
collections,
categories,
onSelectItem,
onHover,
showMostUsedBlocks,
className,
} ) {
const suggestedItems = useMemo( () => {
return orderBy( items, 'frecency', 'desc' ).slice(
0,
Expand All @@ -47,24 +47,6 @@ export function BlockTypesTab(
return items.filter( ( item ) => ! item.category );
}, [ items ] );

const itemsPerCategory = useMemo( () => {
return pipe(
( itemList ) =>
itemList.filter(
( item ) => item.category && item.category !== 'reusable'
),
( itemList ) =>
itemList.reduce( ( acc, item ) => {
const { category } = item;
if ( ! acc[ category ] ) {
acc[ category ] = [];
}
acc[ category ].push( item );
return acc;
}, {} )
)( items );
}, [ items ] );

const itemsPerCollection = useMemo( () => {
// Create a new Object to avoid mutating collection.
const result = { ...collections };
Expand Down Expand Up @@ -101,14 +83,13 @@ export function BlockTypesTab(
didRenderAllCategories ? collectionEntries : EMPTY_ARRAY
);

if ( ! items.length ) {
return <InserterNoResults />;
}

return (
<InserterListbox>
<div ref={ ref }>
{ showMostUsedBlocks && !! suggestedItems.length && (
<div className={ className }>
{ showMostUsedBlocks &&
// Only show the most used blocks if the total amount of block
// is larger than 1 row, otherwise it is not so useful.
items.length > 3 &&
!! suggestedItems.length && (
<InserterPanel title={ _x( 'Most used', 'blocks' ) }>
<BlockTypesList
items={ suggestedItems }
Expand All @@ -119,64 +100,125 @@ export function BlockTypesTab(
</InserterPanel>
) }

{ currentlyRenderedCategories.map( ( category ) => {
const categoryItems = itemsPerCategory[ category.slug ];
if ( ! categoryItems || ! categoryItems.length ) {
{ currentlyRenderedCategories.map( ( category ) => {
const categoryItems = items.filter(
( item ) => item.category === category.slug
);
if ( ! categoryItems || ! categoryItems.length ) {
return null;
}
return (
<InserterPanel
key={ category.slug }
title={ category.title }
icon={ category.icon }
>
<BlockTypesList
items={ categoryItems }
onSelect={ onSelectItem }
onHover={ onHover }
label={ category.title }
/>
</InserterPanel>
);
} ) }

{ didRenderAllCategories && uncategorizedItems.length > 0 && (
<InserterPanel
className="block-editor-inserter__uncategorized-blocks-panel"
title={ __( 'Uncategorized' ) }
>
<BlockTypesList
items={ uncategorizedItems }
onSelect={ onSelectItem }
onHover={ onHover }
label={ __( 'Uncategorized' ) }
/>
</InserterPanel>
) }

{ currentlyRenderedCollections.map(
( [ namespace, collection ] ) => {
const collectionItems = itemsPerCollection[ namespace ];
if ( ! collectionItems || ! collectionItems.length ) {
return null;
}

return (
<InserterPanel
key={ category.slug }
title={ category.title }
icon={ category.icon }
key={ namespace }
title={ collection.title }
icon={ collection.icon }
>
<BlockTypesList
items={ categoryItems }
items={ collectionItems }
onSelect={ onSelectItem }
onHover={ onHover }
label={ category.title }
label={ collection.title }
/>
</InserterPanel>
);
} ) }
}
) }
</div>
);
}

{ didRenderAllCategories && uncategorizedItems.length > 0 && (
<InserterPanel
className="block-editor-inserter__uncategorized-blocks-panel"
title={ __( 'Uncategorized' ) }
>
<BlockTypesList
items={ uncategorizedItems }
onSelect={ onSelectItem }
export function BlockTypesTab(
{ rootClientId, onInsert, onHover, showMostUsedBlocks },
ref
) {
const [ items, categories, collections, onSelectItem ] = useBlockTypesState(
rootClientId,
onInsert
);

if ( ! items.length ) {
return <InserterNoResults />;
}

const itemsForCurrentRoot = [];
const itemsRemaining = [];

for ( const item of items ) {
// Skip reusable blocks, they moved to the patterns tab.
if ( item.category === 'reusable' ) {
continue;
}

if ( rootClientId && item.rootClientId === rootClientId ) {
itemsForCurrentRoot.push( item );
} else {
itemsRemaining.push( item );
}
}

return (
<InserterListbox>
<div ref={ ref }>
{ !! itemsForCurrentRoot.length && (
<>
<BlockTypesTabPanel
items={ itemsForCurrentRoot }
categories={ categories }
collections={ collections }
onSelectItem={ onSelectItem }
onHover={ onHover }
label={ __( 'Uncategorized' ) }
showMostUsedBlocks={ showMostUsedBlocks }
className="block-editor-inserter__insertable-blocks-at-selection"
/>
</InserterPanel>
) }

{ currentlyRenderedCollections.map(
( [ namespace, collection ] ) => {
const collectionItems = itemsPerCollection[ namespace ];
if ( ! collectionItems || ! collectionItems.length ) {
return null;
}

return (
<InserterPanel
key={ namespace }
title={ collection.title }
icon={ collection.icon }
>
<BlockTypesList
items={ collectionItems }
onSelect={ onSelectItem }
onHover={ onHover }
label={ collection.title }
/>
</InserterPanel>
);
}
<hr />
</>
) }
<BlockTypesTabPanel
items={ itemsRemaining }
categories={ categories }
collections={ collections }
onSelectItem={ onSelectItem }
onHover={ onHover }
showMostUsedBlocks={ showMostUsedBlocks }
className="block-editor-inserter__all-blocks"
/>
</div>
</InserterListbox>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,24 @@ import { useCallback } from '@wordpress/element';
* Internal dependencies
*/
import { store as blockEditorStore } from '../../../store';
import { withRootClientIdOptionKey } from '../../../store/utils';

/**
* Retrieves the block types inserter state.
*
* @param {string=} rootClientId Insertion's root client ID.
* @param {Function} onInsert function called when inserter a list of blocks.
* @param {boolean} isQuick
* @return {Array} Returns the block types state. (block types, categories, collections, onSelect handler)
*/
const useBlockTypesState = ( rootClientId, onInsert ) => {
const useBlockTypesState = ( rootClientId, onInsert, isQuick ) => {
const [ items ] = useSelect(
( select ) => [
select( blockEditorStore ).getInserterItems( rootClientId ),
select( blockEditorStore ).getInserterItems( rootClientId, {
[ withRootClientIdOptionKey ]: ! isQuick,
} ),
],
[ rootClientId ]
[ rootClientId, isQuick ]
);

const [ categories, collections ] = useSelect( ( select ) => {
Expand All @@ -37,7 +41,14 @@ const useBlockTypesState = ( rootClientId, onInsert ) => {

const onSelectItem = useCallback(
(
{ name, initialAttributes, innerBlocks, syncStatus, content },
{
name,
initialAttributes,
innerBlocks,
syncStatus,
content,
rootClientId: _rootClientId,
},
shouldFocusBlock
) => {
const insertedBlock =
Expand All @@ -51,7 +62,12 @@ const useBlockTypesState = ( rootClientId, onInsert ) => {
createBlocksFromInnerBlocksTemplate( innerBlocks )
);

onInsert( insertedBlock, undefined, shouldFocusBlock );
onInsert(
insertedBlock,
undefined,
shouldFocusBlock,
_rootClientId
);
},
[ onInsert ]
);
Expand Down
Loading

0 comments on commit 2367f55

Please sign in to comment.