diff --git a/packages/block-editor/src/components/inserter/block-list.js b/packages/block-editor/src/components/inserter/block-list.js
index a1aafcd54061de..26ad6229546530 100644
--- a/packages/block-editor/src/components/inserter/block-list.js
+++ b/packages/block-editor/src/components/inserter/block-list.js
@@ -4,7 +4,6 @@
import {
map,
includes,
- filter,
findIndex,
flow,
sortBy,
@@ -119,20 +118,25 @@ function InserterBlockList( {
}, [ filterValue, items, categories, collections ] );
const childItems = useMemo( () => {
- return filter( filteredItems, ( { name } ) =>
+ return filteredItems.filter( ( { name } ) =>
includes( rootChildBlocks, name )
);
}, [ filteredItems, rootChildBlocks ] );
const suggestedItems = useMemo( () => {
- return filter( items, ( item ) => item.utility > 0 ).slice(
- 0,
- MAX_SUGGESTED_ITEMS
- );
+ return items
+ .filter( ( item ) => item.utility > 0 )
+ .slice( 0, MAX_SUGGESTED_ITEMS );
}, [ items ] );
const reusableItems = useMemo( () => {
- return filter( filteredItems, { category: 'reusable' } );
+ return filteredItems.filter(
+ ( { category } ) => category === 'reusable'
+ );
+ }, [ filteredItems ] );
+
+ const uncategorizedItems = useMemo( () => {
+ return filteredItems.filter( ( item ) => ! item.category );
}, [ filteredItems ] );
const itemsPerCategory = useMemo( () => {
@@ -145,7 +149,9 @@ function InserterBlockList( {
return flow(
( itemList ) =>
- filter( itemList, ( item ) => item.category !== 'reusable' ),
+ itemList.filter(
+ ( item ) => item.category && item.category !== 'reusable'
+ ),
( itemList ) => sortBy( itemList, getCategoryIndex ),
( itemList ) => groupBy( itemList, 'category' )
)( filteredItems );
@@ -228,6 +234,19 @@ function InserterBlockList( {
);
} ) }
+ { ! hasChildItems && !! uncategorizedItems.length && (
+
+
+
+ ) }
+
{ ! hasChildItems &&
map( collections, ( collection, namespace ) => {
const collectionItems = itemsPerCollection[ namespace ];
diff --git a/packages/blocks/src/api/registration.js b/packages/blocks/src/api/registration.js
index 6b165502173feb..d20af322af4fd2 100644
--- a/packages/blocks/src/api/registration.js
+++ b/packages/blocks/src/api/registration.js
@@ -1,4 +1,4 @@
-/* eslint no-console: [ 'error', { allow: [ 'error' ] } ] */
+/* eslint no-console: [ 'error', { allow: [ 'error', 'warn' ] } ] */
/**
* External dependencies
@@ -203,20 +203,20 @@ export function registerBlockType( name, settings ) {
console.error( 'The "edit" property must be a valid function.' );
return;
}
- if ( ! ( 'category' in settings ) ) {
- console.error( 'The block "' + name + '" must have a category.' );
- return;
- }
if (
'category' in settings &&
! some( select( 'core/blocks' ).getCategories(), {
slug: settings.category,
} )
) {
- console.error(
- 'The block "' + name + '" must have a registered category.'
+ console.warn(
+ 'The block "' +
+ name +
+ '" is registered with an invalid category "' +
+ settings.category +
+ '".'
);
- return;
+ delete settings.category;
}
if ( ! ( 'title' in settings ) || settings.title === '' ) {
console.error( 'The block "' + name + '" must have a title.' );
diff --git a/packages/blocks/src/api/test/registration.js b/packages/blocks/src/api/test/registration.js
index d61b6501ae2d1c..08e4c11153e347 100644
--- a/packages/blocks/src/api/test/registration.js
+++ b/packages/blocks/src/api/test/registration.js
@@ -173,23 +173,7 @@ describe( 'blocks', () => {
expect( block ).toBeUndefined();
} );
- it( 'should reject blocks without category', () => {
- const blockType = {
- settingName: 'settingValue',
- save: noop,
- title: 'block title',
- },
- block = registerBlockType(
- 'my-plugin/fancy-block-8',
- blockType
- );
- expect( console ).toHaveErroredWith(
- 'The block "my-plugin/fancy-block-8" must have a category.'
- );
- expect( block ).toBeUndefined();
- } );
-
- it( 'should reject blocks with non registered category.', () => {
+ it( 'should unset category of blocks with non registered category.', () => {
const blockType = {
save: noop,
category: 'custom-category-slug',
@@ -199,10 +183,11 @@ describe( 'blocks', () => {
'my-plugin/fancy-block-9',
blockType
);
- expect( console ).toHaveErroredWith(
- 'The block "my-plugin/fancy-block-9" must have a registered category.'
+ expect( console ).toHaveWarnedWith(
+ 'The block "my-plugin/fancy-block-9" is registered with an invalid category "custom-category-slug".'
);
- expect( block ).toBeUndefined();
+ expect( block ).not.toBeUndefined();
+ expect( block.category ).toBeUndefined();
} );
it( 'should reject blocks without title', () => {
diff --git a/packages/blocks/src/store/test/selectors.js b/packages/blocks/src/store/test/selectors.js
index 8ee2fd064bbff7..636228f7835acb 100644
--- a/packages/blocks/src/store/test/selectors.js
+++ b/packages/blocks/src/store/test/selectors.js
@@ -1,6 +1,8 @@
/**
* External dependencies
*/
+import { omit } from 'lodash';
+
import deepFreeze from 'deep-freeze';
/**
@@ -243,6 +245,7 @@ describe( 'selectors', () => {
describe.each( [
[ 'name', name ],
[ 'block type', blockType ],
+ [ 'block type without category', omit( blockType, 'category' ) ],
] )( 'by %s', ( label, nameOrType ) => {
it( 'should return false if not match', () => {
const result = isMatchingSearchTerm(
@@ -304,15 +307,17 @@ describe( 'selectors', () => {
expect( result ).toBe( true );
} );
- it( 'should return true if match using the categories', () => {
- const result = isMatchingSearchTerm(
- state,
- nameOrType,
- 'COMMON'
- );
-
- expect( result ).toBe( true );
- } );
+ if ( nameOrType.category ) {
+ it( 'should return true if match using the categories', () => {
+ const result = isMatchingSearchTerm(
+ state,
+ nameOrType,
+ 'COMMON'
+ );
+
+ expect( result ).toBe( true );
+ } );
+ }
} );
} );
diff --git a/packages/edit-post/src/components/manage-blocks-modal/category.js b/packages/edit-post/src/components/manage-blocks-modal/category.js
index 5df158fe254333..3169115c86b83b 100644
--- a/packages/edit-post/src/components/manage-blocks-modal/category.js
+++ b/packages/edit-post/src/components/manage-blocks-modal/category.js
@@ -19,7 +19,7 @@ import EditPostSettings from '../edit-post-settings';
function BlockManagerCategory( {
instanceId,
- category,
+ title,
blockTypes,
hiddenBlockTypes,
toggleVisible,
@@ -70,7 +70,7 @@ function BlockManagerCategory( {
onChange={ toggleAllVisible }
className="edit-post-manage-blocks-modal__category-title"
aria-checked={ ariaChecked }
- label={ { category.title } }
+ label={ { title } }
/>
(
) ) }
+ ! category
+ ) }
+ />
);