diff --git a/packages/editor/src/components/default-block-appender/test/__snapshots__/index.js.snap b/packages/editor/src/components/default-block-appender/test/__snapshots__/index.js.snap index 46c017374b5149..71484219b7d98e 100644 --- a/packages/editor/src/components/default-block-appender/test/__snapshots__/index.js.snap +++ b/packages/editor/src/components/default-block-appender/test/__snapshots__/index.js.snap @@ -23,7 +23,7 @@ exports[`DefaultBlockAppender should append a default block when input focused 1 value="Write your story" /> - @@ -45,7 +45,7 @@ exports[`DefaultBlockAppender should match snapshot 1`] = ` value="Write your story" /> - @@ -67,7 +67,7 @@ exports[`DefaultBlockAppender should optionally show without prompt 1`] = ` value="" /> - diff --git a/packages/editor/src/components/inserter/index.js b/packages/editor/src/components/inserter/index.js index d10f70e315af2c..1879683b3c072a 100644 --- a/packages/editor/src/components/inserter/index.js +++ b/packages/editor/src/components/inserter/index.js @@ -3,10 +3,9 @@ */ import { __ } from '@wordpress/i18n'; import { Dropdown, IconButton } from '@wordpress/components'; -import { createBlock, isUnmodifiedDefaultBlock } from '@wordpress/blocks'; import { Component } from '@wordpress/element'; -import { withSelect, withDispatch } from '@wordpress/data'; -import { compose } from '@wordpress/compose'; +import { withSelect } from '@wordpress/data'; +import { compose, ifCondition } from '@wordpress/compose'; /** * Internal dependencies @@ -30,6 +29,8 @@ class Inserter extends Component { super( ...arguments ); this.onToggle = this.onToggle.bind( this ); + this.renderToggle = this.renderToggle.bind( this ); + this.renderContent = this.renderContent.bind( this ); } onToggle( isOpen ) { @@ -41,20 +42,46 @@ class Inserter extends Component { } } - render() { + /** + * Render callback to display Dropdown toggle element. + * + * @param {Function} options.onToggle Callback to invoke when toggle is + * pressed. + * @param {boolean} options.isOpen Whether dropdown is currently open. + * + * @return {WPElement} Dropdown toggle element. + */ + renderToggle( { onToggle, isOpen } ) { const { - items, - position, - title, - onInsertBlock, - rootClientId, disabled, renderToggle = defaultRenderToggle, } = this.props; - if ( items.length === 0 ) { - return null; - } + return renderToggle( { onToggle, isOpen, disabled } ); + } + + /** + * Render callback to display Dropdown content element. + * + * @param {Function} options.onClose Callback to invoke when dropdown is + * closed. + * + * @return {WPElement} Dropdown content element. + */ + renderContent( { onClose } ) { + const { rootClientId, index } = this.props; + + return ( + + ); + } + + render() { + const { position, title } = this.props; return ( renderToggle( { onToggle, isOpen, disabled } ) } - renderContent={ ( { onClose } ) => { - const onSelect = ( item ) => { - onInsertBlock( item ); - - onClose(); - }; - - return ( - - ); - } } + renderToggle={ this.renderToggle } + renderContent={ this.renderContent } /> ); } @@ -90,7 +103,6 @@ export default compose( [ const { getEditedPostAttribute, getBlockInsertionPoint, - getSelectedBlock, getInserterItems, } = select( 'core/editor' ); @@ -106,21 +118,10 @@ export default compose( [ return { title: getEditedPostAttribute( 'title' ), - selectedBlock: getSelectedBlock(), - items: getInserterItems( rootClientId ), - index, + hasItems: getInserterItems( rootClientId ).length > 0, rootClientId, + index, }; } ), - withDispatch( ( dispatch, ownProps ) => ( { - onInsertBlock: ( item ) => { - const { selectedBlock, index, rootClientId } = ownProps; - const { name, initialAttributes } = item; - const insertedBlock = createBlock( name, initialAttributes ); - if ( selectedBlock && isUnmodifiedDefaultBlock( selectedBlock ) ) { - return dispatch( 'core/editor' ).replaceBlocks( selectedBlock.clientId, insertedBlock ); - } - return dispatch( 'core/editor' ).insertBlock( insertedBlock, index, rootClientId ); - }, - } ) ), + ifCondition( ( { hasItems } ) => hasItems ), ] )( Inserter ); diff --git a/packages/editor/src/components/inserter/menu.js b/packages/editor/src/components/inserter/menu.js index 4bb2362377c390..9780661f6442f9 100644 --- a/packages/editor/src/components/inserter/menu.js +++ b/packages/editor/src/components/inserter/menu.js @@ -23,7 +23,12 @@ import scrollIntoView from 'dom-scroll-into-view'; import { __, _n, _x, sprintf } from '@wordpress/i18n'; import { Component, findDOMNode, createRef } from '@wordpress/element'; import { withSpokenMessages, PanelBody } from '@wordpress/components'; -import { getCategories, isReusableBlock } from '@wordpress/blocks'; +import { + getCategories, + isReusableBlock, + createBlock, + isUnmodifiedDefaultBlock, +} from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { withInstanceId, compose, withSafeTimeout } from '@wordpress/compose'; import { LEFT, RIGHT, UP, DOWN, BACKSPACE, ENTER } from '@wordpress/keycodes'; @@ -340,21 +345,55 @@ export class InserterMenu extends Component { export default compose( withSelect( ( select, { rootClientId } ) => { const { - getChildBlockNames, - } = select( 'core/blocks' ); - const { + getEditedPostAttribute, + getSelectedBlock, + getInserterItems, getBlockName, } = select( 'core/editor' ); + const { + getChildBlockNames, + } = select( 'core/blocks' ); + const rootBlockName = getBlockName( rootClientId ); + return { + selectedBlock: getSelectedBlock(), rootChildBlocks: getChildBlockNames( rootBlockName ), + title: getEditedPostAttribute( 'title' ), + items: getInserterItems( rootClientId ), + rootClientId, + }; + } ), + withDispatch( ( dispatch, ownProps ) => { + const { + __experimentalFetchReusableBlocks: fetchReusableBlocks, + showInsertionPoint, + hideInsertionPoint, + } = dispatch( 'core/editor' ); + + return { + fetchReusableBlocks, + showInsertionPoint, + hideInsertionPoint, + onSelect( item ) { + const { + replaceBlocks, + insertBlock, + } = dispatch( 'core/editor' ); + const { selectedBlock, index, rootClientId } = ownProps; + const { name, initialAttributes } = item; + + const insertedBlock = createBlock( name, initialAttributes ); + if ( selectedBlock && isUnmodifiedDefaultBlock( selectedBlock ) ) { + replaceBlocks( selectedBlock.clientId, insertedBlock ); + } else { + insertBlock( insertedBlock, index, rootClientId ); + } + + ownProps.onSelect(); + }, }; } ), - withDispatch( ( dispatch ) => ( { - fetchReusableBlocks: dispatch( 'core/editor' ).__experimentalFetchReusableBlocks, - showInsertionPoint: dispatch( 'core/editor' ).showInsertionPoint, - hideInsertionPoint: dispatch( 'core/editor' ).hideInsertionPoint, - } ) ), withSpokenMessages, withInstanceId, withSafeTimeout