From 9cec012d71a802fe5a253b9427ebabd8b240e500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 11 Jul 2018 17:38:02 +0200 Subject: [PATCH] Allow plugins to extend the BlockSettingsMenu --- .../components/block-settings-menu/index.js | 4 ++ edit-post/index.js | 1 + .../block-settings-menu-plugins-group.js | 33 ++++++++++++ .../block-settings-menu-plugins-item.js | 52 +++++++++++++++++++ .../components/block-settings-menu/index.js | 2 + editor/components/index.js | 1 + 6 files changed, 93 insertions(+) create mode 100644 edit-post/components/block-settings-menu/index.js create mode 100644 editor/components/block-settings-menu/block-settings-menu-plugins-group.js create mode 100644 editor/components/block-settings-menu/block-settings-menu-plugins-item.js diff --git a/edit-post/components/block-settings-menu/index.js b/edit-post/components/block-settings-menu/index.js new file mode 100644 index 0000000000000..6a39f6f82c95a --- /dev/null +++ b/edit-post/components/block-settings-menu/index.js @@ -0,0 +1,4 @@ +import { _BlockSettingsMenuPluginsItem } from '@wordpress/editor'; + +const PluginBlockSettingsMenuItem = _BlockSettingsMenuPluginsItem; +export default PluginBlockSettingsMenuItem; diff --git a/edit-post/index.js b/edit-post/index.js index ebb223771a357..fe1bafd1797e4 100644 --- a/edit-post/index.js +++ b/edit-post/index.js @@ -83,6 +83,7 @@ export function initializeEditor( id, postType, postId, settings, overridePost ) }; } +export { default as PluginBlockSettingsMenuItem } from './components/block-settings-menu'; export { default as PluginPostPublishPanel } from './components/sidebar/plugin-post-publish-panel'; export { default as PluginPostStatusInfo } from './components/sidebar/plugin-post-status-info'; export { default as PluginPrePublishPanel } from './components/sidebar/plugin-pre-publish-panel'; diff --git a/editor/components/block-settings-menu/block-settings-menu-plugins-group.js b/editor/components/block-settings-menu/block-settings-menu-plugins-group.js new file mode 100644 index 0000000000000..41c8aaf113ed7 --- /dev/null +++ b/editor/components/block-settings-menu/block-settings-menu-plugins-group.js @@ -0,0 +1,33 @@ +/** + * External dependencies + */ +import { isEmpty, map } from 'lodash'; + +/** + * WordPress dependencies + */ +import { createSlotFill } from '@wordpress/components'; +import { Fragment } from '@wordpress/element'; +import { withSelect } from '@wordpress/data'; + +const { Fill: BlockSettingsMenuPluginsGroup, Slot } = createSlotFill( 'BlockSettingsMenuPluginsGroup' ); + +const BlockSettingsMenuPluginsGroupSlot = ( { fillProps, selectedBlocks } ) => { + selectedBlocks = map( selectedBlocks, ( block ) => block.name ); + return ( + + { ( fills ) => ! isEmpty( fills ) && ( + +
+ { fills } + + ) } + + ); +}; + +BlockSettingsMenuPluginsGroup.Slot = withSelect( ( select, { fillProps: { uids } } ) => ( { + selectedBlocks: select( 'core/editor' ).getBlocksByUID( uids ), +} ) )( BlockSettingsMenuPluginsGroupSlot ); + +export default BlockSettingsMenuPluginsGroup; diff --git a/editor/components/block-settings-menu/block-settings-menu-plugins-item.js b/editor/components/block-settings-menu/block-settings-menu-plugins-item.js new file mode 100644 index 0000000000000..e20e7da782eaf --- /dev/null +++ b/editor/components/block-settings-menu/block-settings-menu-plugins-item.js @@ -0,0 +1,52 @@ +/** + * External dependencies + */ +import { difference } from 'lodash'; + +/** + * WordPress dependencies + */ +import { IconButton } from '@wordpress/components'; +import { compose } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import BlockSettingsMenuPluginsGroup from './block-settings-menu-plugins-group'; + +const isEverySelectedBlockAllowed = ( selected, allowed ) => difference( selected, allowed ).length === 0; + +/** + * Plugins may want to add an item to the menu either for every block + * or only for the specific ones provided in the `allowedBlocks` component property. + * + * If there are multiple blocks selected the item will be rendered if every block + * is of one allowed type (not necesarily the same). + * + * @param {string[]} selectedBlockNames Array containing the names of the blocks selected + * @param {string[]} allowedBlockNames Array containing the names of the blocks allowed + * @return {boolean} Whether the item will be rendered or not. + */ +const shouldRenderItem = ( selectedBlockNames, allowedBlockNames ) => ! Array.isArray( allowedBlockNames ) || + isEverySelectedBlockAllowed( selectedBlockNames, allowedBlockNames ); + +const BlockSettingsMenuPluginsItem = ( { allowedBlocks, icon, label, onClick, small, role } ) => ( + + { ( { selectedBlocks, onClose } ) => { + if ( ! shouldRenderItem( selectedBlocks, allowedBlocks ) ) { + return null; + } + return ( + { ! small && label } + ); + } } + +); + +export default BlockSettingsMenuPluginsItem; diff --git a/editor/components/block-settings-menu/index.js b/editor/components/block-settings-menu/index.js index 3491ee7f8be3b..c261255ebb141 100644 --- a/editor/components/block-settings-menu/index.js +++ b/editor/components/block-settings-menu/index.js @@ -26,6 +26,7 @@ import BlockHTMLConvertButton from './block-html-convert-button'; import BlockUnknownConvertButton from './block-unknown-convert-button'; import _BlockSettingsMenuFirstItem from './block-settings-menu-first-item'; import withDeprecatedUniqueId from '../with-deprecated-unique-id'; +import _BlockSettingsMenuPluginsGroup from './block-settings-menu-plugins-group'; export class BlockSettingsMenu extends Component { constructor() { @@ -127,6 +128,7 @@ export class BlockSettingsMenu extends Component { itemsRole="menuitem" /> ) } + <_BlockSettingsMenuPluginsGroup.Slot fillProps={ { clientIds, onClose } } />
{ count === 1 && (