Skip to content

Commit

Permalink
Improve child blocks API's and UI.
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed May 29, 2018
1 parent 400f8fc commit cc62ab9
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 7 deletions.
2 changes: 2 additions & 0 deletions blocks/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export {
getBlockSupport,
hasBlockSupport,
isSharedBlock,
getChildBlockNames,
hasChildBlocks,
} from './registration';
export {
isUnmodifiedDefaultBlock,
Expand Down
22 changes: 22 additions & 0 deletions blocks/api/registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,3 +288,25 @@ export function hasBlockSupport( nameOrType, feature, defaultSupports ) {
export function isSharedBlock( blockOrType ) {
return blockOrType.name === 'core/block';
}
/**
* Returns an array with the child blocks of a given block.
*
* @param {string} blockName Block type name.
*
* @return {Array} Array of child block names.
*/

export const getChildBlockNames = ( blockName ) => {
return select( 'core/blocks' ).getChildBlockNames( blockName );
};

/**
* Returns a boolean indicating if a block has child blocks or not.
*
* @param {string} blockName Block type name.
*
* @return {boolean} True if a block contains child blocks and false otherwise.
*/
export const hasChildBlocks = ( blockName ) => {
return select( 'core/blocks' ).hasChildBlocks( blockName );
};
35 changes: 35 additions & 0 deletions blocks/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* External dependencies
*/
import createSelector from 'rememo';
import { filter, includes, map } from 'lodash';

/**
* Returns all the available block types.
Expand Down Expand Up @@ -61,3 +62,37 @@ export function getDefaultBlockName( state ) {
export function getFallbackBlockName( state ) {
return state.fallbackBlockName;
}

/**
* Returns an array with the child blocks of a given block.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
*
* @return {Array} Array of child block names.
*/
export const getChildBlockNames = createSelector(
( state, blockName ) => {
return map(
filter( state.blockTypes, ( blockType ) => {
return includes( blockType.parent, blockName );
} ),
( { name } ) => name
);
},
( state ) => [
state.blockTypes,
]
);

/**
* Returns a boolean indicating if a block has child blocks or not.
*
* @param {Object} state Data state.
* @param {string} blockName Block type name.
*
* @return {boolean} True if a block contains child blocks and false otherwise.
*/
export const hasChildBlocks = ( state, blockName ) => {
return getChildBlockNames( state, blockName ).length > 0;
};
4 changes: 3 additions & 1 deletion editor/components/inserter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Inserter extends Component {
title,
children,
onInsertBlock,
rootUID,
} = this.props;

if ( items.length === 0 ) {
Expand Down Expand Up @@ -74,7 +75,7 @@ class Inserter extends Component {
onClose();
};

return <InserterMenu items={ items } onSelect={ onSelect } />;
return <InserterMenu items={ items } onSelect={ onSelect } rootUID={ rootUID } />;
} }
/>
);
Expand All @@ -96,6 +97,7 @@ export default compose( [
insertionPoint,
selectedBlock: getSelectedBlock(),
items: getInserterItems( rootUID ),
rootUID,
};
} ),
withDispatch( ( dispatch, ownProps ) => ( {
Expand Down
10 changes: 9 additions & 1 deletion editor/components/inserter/item-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,15 @@ class ItemList extends Component {
<button
role="menuitem"
key={ item.id }
className={ classnames( 'editor-inserter__item', getBlockMenuDefaultClassName( item.id ) ) }
className={
classnames(
'editor-inserter__item',
getBlockMenuDefaultClassName( item.id ),
{
'editor-inserter__item-with-childs': item.hasChildBlocks,
}
)
}
onClick={ () => onSelect( item ) }
tabIndex={ isCurrent || item.isDisabled ? null : '-1' }
disabled={ item.isDisabled }
Expand Down
44 changes: 40 additions & 4 deletions editor/components/inserter/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
findIndex,
find,
without,
includes,
} from 'lodash';

/**
Expand All @@ -24,14 +25,15 @@ import {
PanelBody,
} from '@wordpress/components';
import { getCategories, isSharedBlock } from '@wordpress/blocks';
import { withDispatch } from '@wordpress/data';
import { withDispatch, withSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import './style.scss';
import BlockPreview from '../block-preview';
import ItemList from './item-list';
import BlockIcon from '../block-icon';

const MAX_SUGGESTED_ITEMS = 9;

Expand All @@ -56,6 +58,7 @@ export class InserterMenu extends Component {
constructor() {
super( ...arguments );
this.state = {
childItems: [],
filterValue: '',
hoveredItem: null,
suggestedItems: [],
Expand Down Expand Up @@ -108,9 +111,13 @@ export class InserterMenu extends Component {
}

filter( filterValue = '' ) {
const { items } = this.props;
const { items, rootChildBlocks } = this.props;
const filteredItems = searchItems( items, filterValue );

const childItems = rootChildBlocks ?
filter( filteredItems, ( { name } ) => includes( rootChildBlocks, name ) ) :
[];

let suggestedItems = [];
if ( ! filterValue ) {
const maxSuggestedItems = this.props.maxSuggestedItems || MAX_SUGGESTED_ITEMS;
Expand Down Expand Up @@ -142,6 +149,7 @@ export class InserterMenu extends Component {

this.setState( {
hoveredItem: null,
childItems,
filterValue,
suggestedItems,
sharedItems,
Expand All @@ -151,8 +159,8 @@ export class InserterMenu extends Component {
}

render() {
const { instanceId, onSelect } = this.props;
const { hoveredItem, suggestedItems, sharedItems, itemsPerCategory, openPanels } = this.state;
const { instanceId, onSelect, rootBlockIcon, rootBlockTitle } = this.props;
const { childItems, hoveredItem, suggestedItems, sharedItems, itemsPerCategory, openPanels } = this.state;
const isPanelOpen = ( panel ) => openPanels.indexOf( panel ) !== -1;

// Disable reason: The inserter menu is a modal display, not one which
Expand All @@ -175,6 +183,18 @@ export class InserterMenu extends Component {
/>

<div className="editor-inserter__results">
{ !! childItems.length &&
<div className="editor-inserter__child-blocks">
<div className="editor-inserter__child-blocks-title">
<BlockIcon icon={ rootBlockIcon } />
<h2>
{ rootBlockTitle }
</h2>
</div>
<ItemList items={ childItems } onSelect={ onSelect } onHover={ this.onHover } />
</div>
}

{ !! suggestedItems.length &&
<PanelBody
title={ __( 'Most Used' ) }
Expand Down Expand Up @@ -223,6 +243,22 @@ export class InserterMenu extends Component {
}

export default compose(
withSelect( ( select, { rootUID } ) => {
const {
getChildBlockNames,
getBlockType,
} = select( 'core/blocks' );
const {
getBlockName,
} = select( 'core/editor' );
const rootBlockName = getBlockName( rootUID );
const rootBlockType = getBlockType( rootBlockName );
return {
rootBlockTitle: rootBlockType && rootBlockType.title,
rootBlockIcon: rootBlockType && rootBlockType.icon,
rootChildBlocks: getChildBlockNames( rootBlockName ),
};
} ),
withDispatch( ( dispatch ) => ( {
fetchSharedBlocks: dispatch( 'core/editor' ).fetchSharedBlocks,
} ) ),
Expand Down
25 changes: 25 additions & 0 deletions editor/components/inserter/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,28 @@ input[type="search"].editor-inserter__search {
.editor-inserter__item-title {
padding: 4px 2px;
}

.editor-inserter__item-with-childs .editor-inserter__item-icon {
background: #7E70AF;
box-shadow: 3px 3px #AEA6CC;
margin-right: 3px;
color: white;
}

.editor-inserter__child-blocks {
padding: 16px;
}

.editor-inserter__child-blocks-title .dashicon {
display: inline-block;
margin-right: 10px;
}

.editor-inserter__child-blocks-title h2 {
display: inline-block;
}

.editor-inserter__child-blocks .editor-inserter__item-icon {
background: 3px 3px #AEA6CC;
color: white;
}
3 changes: 2 additions & 1 deletion editor/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import createSelector from 'rememo';
/**
* WordPress dependencies
*/
import { serialize, getBlockType, getBlockTypes, hasBlockSupport } from '@wordpress/blocks';
import { serialize, getBlockType, getBlockTypes, hasBlockSupport, hasChildBlocks } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { moment } from '@wordpress/date';
import { deprecated } from '@wordpress/utils';
Expand Down Expand Up @@ -1404,6 +1404,7 @@ export const getInserterItems = createSelector(
isDisabled,
utility: calculateUtility( blockType.category, count, isContextual ),
frecency: calculateFrecency( time, count ),
hasChildBlocks: hasChildBlocks( blockType.name ),
};
};

Expand Down

0 comments on commit cc62ab9

Please sign in to comment.