Skip to content

Commit

Permalink
Don't show stacked icon on parent blocks if all of its children are h…
Browse files Browse the repository at this point in the history
…idden from the inserter.
  • Loading branch information
jorgefilipecosta committed Sep 13, 2018
1 parent 6dad836 commit 0dda16e
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 18 deletions.
1 change: 1 addition & 0 deletions packages/blocks/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export {
isReusableBlock,
getChildBlockNames,
hasChildBlocks,
hasChildBlocksWithInserterSupport,
unstable__bootstrapServerSideBlockDefinitions, // eslint-disable-line camelcase
registerBlockStyle,
} from './registration';
Expand Down
26 changes: 16 additions & 10 deletions packages/blocks/src/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,17 +235,11 @@ export function getBlockTypes() {
* @param {string} feature Feature to retrieve
* @param {*} defaultSupports Default value to return if not
* explicitly defined
* @return {?*} Block support value
*
* @return {?*} Block support value
*/
export function getBlockSupport( nameOrType, feature, defaultSupports ) {
const blockType = 'string' === typeof nameOrType ?
getBlockType( nameOrType ) :
nameOrType;

return get( blockType, [
'supports',
feature,
], defaultSupports );
return select( 'core/blocks' ).getBlockSupport( nameOrType, feature, defaultSupports );
}

/**
Expand All @@ -259,7 +253,7 @@ export function getBlockSupport( nameOrType, feature, defaultSupports ) {
* @return {boolean} Whether block supports feature.
*/
export function hasBlockSupport( nameOrType, feature, defaultSupports ) {
return !! getBlockSupport( nameOrType, feature, defaultSupports );
return select( 'core/blocks' ).hasBlockSupport( nameOrType, feature, defaultSupports );
}

/**
Expand Down Expand Up @@ -297,6 +291,18 @@ export const hasChildBlocks = ( blockName ) => {
return select( 'core/blocks' ).hasChildBlocks( blockName );
};

/**
* Returns a boolean indicating if a block has at least one child block with inserter support.
*
* @param {string} blockName Block type name.
*
* @return {boolean} True if a block contains at least one child blocks with inserter support
* and false otherwise.
*/
export const hasChildBlocksWithInserterSupport = ( blockName ) => {
return select( 'core/blocks' ).hasChildBlocksWithInserterSupport( blockName );
};

/**
* Registers a new block style variation for the given block.
*
Expand Down
54 changes: 53 additions & 1 deletion packages/blocks/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import createSelector from 'rememo';
import { filter, includes, map } from 'lodash';
import { filter, get, includes, map, some } from 'lodash';

/**
* Returns all the available block types.
Expand Down Expand Up @@ -85,6 +85,43 @@ export const getChildBlockNames = createSelector(
]
);

/**
* Returns the block support value for a feature, if defined.
*
* @param {Object} state Data state.
* @param {(string|Object)} nameOrType Block name or type object
* @param {string} feature Feature to retrieve
* @param {*} defaultSupports Default value to return if not
* explicitly defined
*
* @return {?*} Block support value
*/
export const getBlockSupport = ( state, nameOrType, feature, defaultSupports ) => {
const blockType = 'string' === typeof nameOrType ?
getBlockType( state, nameOrType ) :
nameOrType;

return get( blockType, [
'supports',
feature,
], defaultSupports );
};

/**
* Returns true if the block defines support for a feature, or false otherwise.
*
* @param {Object} state Data state.
* @param {(string|Object)} nameOrType Block name or type object.
* @param {string} feature Feature to test.
* @param {boolean} defaultSupports Whether feature is supported by
* default if not explicitly defined.
*
* @return {boolean} Whether block supports feature.
*/
export function hasBlockSupport( state, nameOrType, feature, defaultSupports ) {
return !! getBlockSupport( state, nameOrType, feature, defaultSupports );
}

/**
* Returns a boolean indicating if a block has child blocks or not.
*
Expand All @@ -96,3 +133,18 @@ export const getChildBlockNames = createSelector(
export const hasChildBlocks = ( state, blockName ) => {
return getChildBlockNames( state, blockName ).length > 0;
};

/**
* Returns a boolean indicating if a block has at least one child block with inserter support.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
*
* @return {boolean} True if a block contains at least one child blocks with inserter support
* and false otherwise.
*/
export const hasChildBlocksWithInserterSupport = ( state, blockName ) => {
return some( getChildBlockNames( state, blockName ), ( childBlockName ) => {
return hasBlockSupport( state, childBlockName, 'inserter', true );
} );
};
4 changes: 2 additions & 2 deletions packages/editor/src/components/block-switcher/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { castArray, filter, first, get, mapKeys, orderBy } from 'lodash';
*/
import { __, _n, sprintf } from '@wordpress/i18n';
import { Dropdown, IconButton, Toolbar, PanelBody, AccessibleSVG } from '@wordpress/components';
import { getBlockType, getPossibleBlockTransformations, switchToBlockType, hasChildBlocks } from '@wordpress/blocks';
import { getBlockType, getPossibleBlockTransformations, switchToBlockType, hasChildBlocksWithInserterSupport } from '@wordpress/blocks';
import { Component, Fragment } from '@wordpress/element';
import { DOWN } from '@wordpress/keycodes';
import { withSelect, withDispatch } from '@wordpress/data';
Expand Down Expand Up @@ -128,7 +128,7 @@ export class BlockSwitcher extends Component {
id: destinationBlockType.name,
icon: destinationBlockType.icon,
title: destinationBlockType.title,
hasChildBlocks: hasChildBlocks( destinationBlockType.name ),
hasChildBlocksWithInserterSupport: hasChildBlocksWithInserterSupport( destinationBlockType.name ),
} ) ) }
onSelect={ ( item ) => {
onTransform( blocks, item.id );
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/components/block-types-list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class BlockTypesList extends Component {
'editor-block-types-list__item',
getBlockMenuDefaultClassName( item.id ),
{
'editor-block-types-list__item-has-children': item.hasChildBlocks,
'editor-block-types-list__item-has-children': item.hasChildBlocksWithInserterSupport,
}
)
}
Expand All @@ -62,7 +62,7 @@ class BlockTypesList extends Component {
style={ itemIconStyle }
>
<BlockIcon icon={ item.icon && item.icon.src } showColors />
{ item.hasChildBlocks &&
{ item.hasChildBlocksWithInserterSupport &&
<span
className="editor-block-types-list__item-icon-stack"
style={ itemIconStackStyle }
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import createSelector from 'rememo';
/**
* WordPress dependencies
*/
import { serialize, getBlockType, getBlockTypes, hasBlockSupport, hasChildBlocks, getUnknownTypeHandlerName } from '@wordpress/blocks';
import { serialize, getBlockType, getBlockTypes, hasBlockSupport, hasChildBlocksWithInserterSupport, getUnknownTypeHandlerName } from '@wordpress/blocks';
import { moment } from '@wordpress/date';
import { removep } from '@wordpress/autop';

Expand Down Expand Up @@ -1571,7 +1571,7 @@ export const getInserterItems = createSelector(
isDisabled,
utility: calculateUtility( blockType.category, count, isContextual ),
frecency: calculateFrecency( time, count ),
hasChildBlocks: hasChildBlocks( blockType.name ),
hasChildBlocksWithInserterSupport: hasChildBlocksWithInserterSupport( blockType.name ),
};
};

Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/store/test/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -3084,7 +3084,7 @@ describe( 'selectors', () => {
isDisabled: false,
utility: 0,
frecency: 0,
hasChildBlocks: false,
hasChildBlocksWithInserterSupport: false,
} );
const reusableBlockItem = items.find( ( item ) => item.id === 'core/block/1' );
expect( reusableBlockItem ).toEqual( {
Expand Down

0 comments on commit 0dda16e

Please sign in to comment.