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 00000000000000..6a39f6f82c95a8
--- /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 ebb223771a3576..fe1bafd1797e43 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 00000000000000..41c8aaf113ed70
--- /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 00000000000000..e20e7da782eaf3
--- /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 3491ee7f8be3be..c261255ebb1419 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 && (