From 59e56dc607b6796d104f21f03ca90e87d4b4a1e0 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Tue, 26 Mar 2019 09:22:53 +0100 Subject: [PATCH] Move the reusable blocks buttons to the editor module (#14387) --- .../developers/data/data-core-block-editor.md | 12 ++++ packages/block-editor/README.md | 12 ---- .../block-editor-keyboard-shortcuts/index.js | 6 +- .../block-settings-menu-first-item.js | 6 +- .../block-settings-menu-plugins-extension.js | 6 +- .../components/block-settings-menu/index.js | 20 ++----- .../src/components/block-toolbar/index.js | 12 ++-- .../src/components/copy-handler/index.js | 11 +--- packages/block-editor/src/components/index.js | 4 +- packages/block-editor/src/store/selectors.js | 32 +++++++++-- .../block-editor/src/store/test/selectors.js | 56 +++++++++++++++++++ .../src/components/visual-editor/index.js | 12 ++-- .../editor/src/components/provider/index.js | 2 + .../reusable-blocks-buttons/index.js | 40 +++++++++++++ .../reusable-block-convert-button.js | 0 .../reusable-block-delete-button.js | 0 .../reusable-block-delete-button.js.snap | 0 .../test/reusable-block-convert-button.js | 0 .../test/reusable-block-delete-button.js | 0 19 files changed, 163 insertions(+), 68 deletions(-) create mode 100644 packages/editor/src/components/reusable-blocks-buttons/index.js rename packages/{block-editor/src/components/block-settings-menu => editor/src/components/reusable-blocks-buttons}/reusable-block-convert-button.js (100%) rename packages/{block-editor/src/components/block-settings-menu => editor/src/components/reusable-blocks-buttons}/reusable-block-delete-button.js (100%) rename packages/{block-editor/src/components/block-settings-menu => editor/src/components/reusable-blocks-buttons}/test/__snapshots__/reusable-block-delete-button.js.snap (100%) rename packages/{block-editor/src/components/block-settings-menu => editor/src/components/reusable-blocks-buttons}/test/reusable-block-convert-button.js (100%) rename packages/{block-editor/src/components/block-settings-menu => editor/src/components/reusable-blocks-buttons}/test/reusable-block-delete-button.js (100%) diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index fb3f337dd59cd..38110f42aa2c7 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -327,6 +327,18 @@ This position is to used to position the caret properly when the selected block Selected block. +### getSelectedBlockClientIds + +Returns the current selection set of block client IDs (multiselection or single selection). + +*Parameters* + + * state: Editor state. + +*Returns* + +Multi-selected block client IDs. + ### getMultiSelectedBlockClientIds Returns the current multi-selection set of block client IDs, or an empty diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index 2543c7affed41..b30502aaf6540 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -520,18 +520,6 @@ font size value retrieval, and font size change handling. Undocumented declaration. -### \_BlockSettingsMenuFirstItem - -[src/index.js#L15-L15](src/index.js#L15-L15) - -Undocumented declaration. - -### \_BlockSettingsMenuPluginsExtension - -[src/index.js#L15-L15](src/index.js#L15-L15) - -Undocumented declaration. - diff --git a/packages/block-editor/src/components/block-editor-keyboard-shortcuts/index.js b/packages/block-editor/src/components/block-editor-keyboard-shortcuts/index.js index 4e97184cd93f9..9b30976a27ee0 100644 --- a/packages/block-editor/src/components/block-editor-keyboard-shortcuts/index.js +++ b/packages/block-editor/src/components/block-editor-keyboard-shortcuts/index.js @@ -123,14 +123,12 @@ export default compose( [ withSelect( ( select ) => { const { getBlockOrder, - getMultiSelectedBlockClientIds, + getSelectedBlockClientIds, hasMultiSelection, getBlockRootClientId, getTemplateLock, - getSelectedBlockClientId, } = select( 'core/block-editor' ); - const selectedBlockClientId = getSelectedBlockClientId(); - const selectedBlockClientIds = selectedBlockClientId ? [ selectedBlockClientId ] : getMultiSelectedBlockClientIds(); + const selectedBlockClientIds = getSelectedBlockClientIds(); return { rootBlocksClientIds: getBlockOrder(), diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-menu-first-item.js b/packages/block-editor/src/components/block-settings-menu/block-settings-menu-first-item.js index ffae5175cb462..e01f943684ffe 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-menu-first-item.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-menu-first-item.js @@ -3,8 +3,8 @@ */ import { createSlotFill } from '@wordpress/components'; -const { Fill: _BlockSettingsMenuFirstItem, Slot } = createSlotFill( '_BlockSettingsMenuFirstItem' ); +const { Fill: __experimentalBlockSettingsMenuFirstItem, Slot } = createSlotFill( '__experimentalBlockSettingsMenuFirstItem' ); -_BlockSettingsMenuFirstItem.Slot = Slot; +__experimentalBlockSettingsMenuFirstItem.Slot = Slot; -export default _BlockSettingsMenuFirstItem; +export default __experimentalBlockSettingsMenuFirstItem; diff --git a/packages/block-editor/src/components/block-settings-menu/block-settings-menu-plugins-extension.js b/packages/block-editor/src/components/block-settings-menu/block-settings-menu-plugins-extension.js index 3357a6592fe0f..a750b5b36cc18 100644 --- a/packages/block-editor/src/components/block-settings-menu/block-settings-menu-plugins-extension.js +++ b/packages/block-editor/src/components/block-settings-menu/block-settings-menu-plugins-extension.js @@ -3,8 +3,8 @@ */ import { createSlotFill } from '@wordpress/components'; -const { Fill: _BlockSettingsMenuPluginsExtension, Slot } = createSlotFill( '_BlockSettingsMenuPluginsExtension' ); +const { Fill: __experimentalBlockSettingsMenuPluginsExtension, Slot } = createSlotFill( '__experimentalBlockSettingsMenuPluginsExtension' ); -_BlockSettingsMenuPluginsExtension.Slot = Slot; +__experimentalBlockSettingsMenuPluginsExtension.Slot = Slot; -export default _BlockSettingsMenuPluginsExtension; +export default __experimentalBlockSettingsMenuPluginsExtension; diff --git a/packages/block-editor/src/components/block-settings-menu/index.js b/packages/block-editor/src/components/block-settings-menu/index.js index 9c3e5b7b707ff..05c023ac43b90 100644 --- a/packages/block-editor/src/components/block-settings-menu/index.js +++ b/packages/block-editor/src/components/block-settings-menu/index.js @@ -18,12 +18,10 @@ import { withDispatch } from '@wordpress/data'; import { shortcuts } from '../block-editor-keyboard-shortcuts'; import BlockActions from '../block-actions'; import BlockModeToggle from './block-mode-toggle'; -import ReusableBlockConvertButton from './reusable-block-convert-button'; -import ReusableBlockDeleteButton from './reusable-block-delete-button'; import BlockHTMLConvertButton from './block-html-convert-button'; import BlockUnknownConvertButton from './block-unknown-convert-button'; -import _BlockSettingsMenuFirstItem from './block-settings-menu-first-item'; -import _BlockSettingsMenuPluginsExtension from './block-settings-menu-plugins-extension'; +import __experimentalBlockSettingsMenuFirstItem from './block-settings-menu-first-item'; +import __experimentalBlockSettingsMenuPluginsExtension from './block-settings-menu-plugins-extension'; export function BlockSettingsMenu( { clientIds, onSelect } ) { const blockClientIds = castArray( clientIds ); @@ -59,7 +57,7 @@ export function BlockSettingsMenu( { clientIds, onSelect } ) { } } renderContent={ ( { onClose } ) => ( - <_BlockSettingsMenuFirstItem.Slot fillProps={ { onClose } } /> + <__experimentalBlockSettingsMenuFirstItem.Slot fillProps={ { onClose } } /> { count === 1 && ( ) } - - <_BlockSettingsMenuPluginsExtension.Slot fillProps={ { clientIds, onClose } } /> + <__experimentalBlockSettingsMenuPluginsExtension.Slot fillProps={ { clientIds, onClose } } />
- { count === 1 && ( - - ) } { ! isLocked && ( { const { - getSelectedBlockClientId, getBlockMode, - getMultiSelectedBlockClientIds, + getSelectedBlockClientIds, isBlockValid, } = select( 'core/block-editor' ); - const selectedBlockClientId = getSelectedBlockClientId(); - const blockClientIds = selectedBlockClientId ? - [ selectedBlockClientId ] : - getMultiSelectedBlockClientIds(); + const blockClientIds = getSelectedBlockClientIds(); return { blockClientIds, - isValid: selectedBlockClientId ? isBlockValid( selectedBlockClientId ) : null, - mode: selectedBlockClientId ? getBlockMode( selectedBlockClientId ) : null, + isValid: blockClientIds.length === 1 ? isBlockValid( blockClientIds[ 0 ] ) : null, + mode: blockClientIds.length === 1 ? getBlockMode( blockClientIds[ 0 ] ) : null, }; } )( BlockToolbar ); diff --git a/packages/block-editor/src/components/copy-handler/index.js b/packages/block-editor/src/components/copy-handler/index.js index 3f73d5f672c15..75b2db4098858 100644 --- a/packages/block-editor/src/components/copy-handler/index.js +++ b/packages/block-editor/src/components/copy-handler/index.js @@ -18,16 +18,13 @@ export default compose( [ withDispatch( ( dispatch, ownProps, { select } ) => { const { getBlocksByClientId, - getMultiSelectedBlockClientIds, - getSelectedBlockClientId, + getSelectedBlockClientIds, hasMultiSelection, } = select( 'core/block-editor' ); const { removeBlocks } = dispatch( 'core/block-editor' ); const onCopy = ( event ) => { - const selectedBlockClientIds = getSelectedBlockClientId() ? - [ getSelectedBlockClientId() ] : - getMultiSelectedBlockClientIds(); + const selectedBlockClientIds = getSelectedBlockClientIds(); if ( selectedBlockClientIds.length === 0 ) { return; @@ -52,9 +49,7 @@ export default compose( [ onCopy( event ); if ( hasMultiSelection() ) { - const selectedBlockClientIds = getSelectedBlockClientId() ? - [ getSelectedBlockClientId() ] : - getMultiSelectedBlockClientIds(); + const selectedBlockClientIds = getSelectedBlockClientIds(); removeBlocks( selectedBlockClientIds ); } diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index aade441e3dde6..c9a454c253d27 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -38,8 +38,8 @@ export { default as BlockList } from './block-list'; export { default as BlockMover } from './block-mover'; export { default as BlockSelectionClearer } from './block-selection-clearer'; export { default as BlockSettingsMenu } from './block-settings-menu'; -export { default as _BlockSettingsMenuFirstItem } from './block-settings-menu/block-settings-menu-first-item'; -export { default as _BlockSettingsMenuPluginsExtension } from './block-settings-menu/block-settings-menu-plugins-extension'; +export { default as __experimentalBlockSettingsMenuFirstItem } from './block-settings-menu/block-settings-menu-first-item'; +export { default as __experimentalBlockSettingsMenuPluginsExtension } from './block-settings-menu/block-settings-menu-plugins-extension'; export { default as BlockTitle } from './block-title'; export { default as BlockToolbar } from './block-toolbar'; export { default as CopyHandler } from './copy-handler'; diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d1b142530cff6..03f0296545709 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -560,18 +560,21 @@ export function getSelectedBlocksInitialCaretPosition( state ) { } /** - * Returns the current multi-selection set of block client IDs, or an empty - * array if there is no multi-selection. + * Returns the current selection set of block client IDs (multiselection or single selection). * * @param {Object} state Editor state. * * @return {Array} Multi-selected block client IDs. */ -export const getMultiSelectedBlockClientIds = createSelector( +export const getSelectedBlockClientIds = createSelector( ( state ) => { const { start, end } = state.blockSelection; + if ( start === null || end === null ) { + return EMPTY_ARRAY; + } + if ( start === end ) { - return []; + return [ start ]; } // Retrieve root client ID to aid in retrieving relevant nested block @@ -579,7 +582,7 @@ export const getMultiSelectedBlockClientIds = createSelector( // by explicitly testing against null. const rootClientId = getBlockRootClientId( state, start ); if ( rootClientId === null ) { - return []; + return EMPTY_ARRAY; } const blockOrder = getBlockOrder( state, rootClientId ); @@ -599,6 +602,23 @@ export const getMultiSelectedBlockClientIds = createSelector( ], ); +/** + * Returns the current multi-selection set of block client IDs, or an empty + * array if there is no multi-selection. + * + * @param {Object} state Editor state. + * + * @return {Array} Multi-selected block client IDs. + */ +export function getMultiSelectedBlockClientIds( state ) { + const { start, end } = state.blockSelection; + if ( start === end ) { + return EMPTY_ARRAY; + } + + return getSelectedBlockClientIds( state ); +} + /** * Returns the current multi-selection set of blocks, or an empty array if * there is no multi-selection. @@ -617,7 +637,7 @@ export const getMultiSelectedBlocks = createSelector( return multiSelectedBlockClientIds.map( ( clientId ) => getBlock( state, clientId ) ); }, ( state ) => [ - ...getMultiSelectedBlockClientIds.getDependants( state ), + ...getSelectedBlockClientIds.getDependants( state ), state.blocks.byClientId, state.blocks.order, state.blocks.attributes, diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index bcda13ad755ff..fde8a74fefa91 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -32,6 +32,7 @@ const { getBlockRootClientId, getBlockHierarchyRootClientId, getGlobalBlockCount, + getSelectedBlockClientIds, getMultiSelectedBlockClientIds, getMultiSelectedBlocks, getMultiSelectedBlocksStartClientId, @@ -984,6 +985,61 @@ describe( 'selectors', () => { } ); } ); + describe( 'getSelectedBlockClientIds', () => { + it( 'should return empty if there is no selection', () => { + const state = { + blocks: { + order: { + '': [ 123, 23 ], + }, + }, + blockSelection: { start: null, end: null }, + }; + + expect( getSelectedBlockClientIds( state ) ).toEqual( [] ); + } ); + + it( 'should return the selected block clientId if there is a selection', () => { + const state = { + blocks: { + order: { + '': [ 5, 4, 3, 2, 1 ], + }, + }, + blockSelection: { start: 2, end: 2 }, + }; + + expect( getSelectedBlockClientIds( state ) ).toEqual( [ 2 ] ); + } ); + + it( 'should return selected block clientIds if there is multi selection', () => { + const state = { + blocks: { + order: { + '': [ 5, 4, 3, 2, 1 ], + }, + }, + blockSelection: { start: 2, end: 4 }, + }; + + expect( getSelectedBlockClientIds( state ) ).toEqual( [ 4, 3, 2 ] ); + } ); + + it( 'should return selected block clientIds if there is multi selection (nested context)', () => { + const state = { + blocks: { + order: { + '': [ 5, 4, 3, 2, 1 ], + 4: [ 9, 8, 7, 6 ], + }, + }, + blockSelection: { start: 7, end: 9 }, + }; + + expect( getSelectedBlockClientIds( state ) ).toEqual( [ 9, 8, 7 ] ); + } ); + } ); + describe( 'getMultiSelectedBlockClientIds', () => { it( 'should return empty if there is no multi selection', () => { const state = { diff --git a/packages/edit-post/src/components/visual-editor/index.js b/packages/edit-post/src/components/visual-editor/index.js index ca6a1c45212b6..8287f5c27396d 100644 --- a/packages/edit-post/src/components/visual-editor/index.js +++ b/packages/edit-post/src/components/visual-editor/index.js @@ -12,8 +12,8 @@ import { CopyHandler, BlockSelectionClearer, MultiSelectScrollIntoView, - _BlockSettingsMenuFirstItem, - _BlockSettingsMenuPluginsExtension, + __experimentalBlockSettingsMenuFirstItem, + __experimentalBlockSettingsMenuPluginsExtension, } from '@wordpress/block-editor'; /** @@ -35,12 +35,12 @@ function VisualEditor() { - <_BlockSettingsMenuFirstItem> + <__experimentalBlockSettingsMenuFirstItem> { ( { onClose } ) => } - - <_BlockSettingsMenuPluginsExtension> + + <__experimentalBlockSettingsMenuPluginsExtension> { ( { clientIds, onClose } ) => } - + ); } diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js index 24ae2e643d4c6..399516dde7bd1 100644 --- a/packages/editor/src/components/provider/index.js +++ b/packages/editor/src/components/provider/index.js @@ -21,6 +21,7 @@ import { decodeEntities } from '@wordpress/html-entities'; */ import transformStyles from '../../editor-styles'; import { mediaUpload } from '../../utils'; +import ReusableBlocksButtons from '../reusable-blocks-buttons'; const fetchLinkSuggestions = async ( search ) => { const posts = await apiFetch( { @@ -154,6 +155,7 @@ class EditorProvider extends Component { settings={ editorSettings } > { children } + ); } diff --git a/packages/editor/src/components/reusable-blocks-buttons/index.js b/packages/editor/src/components/reusable-blocks-buttons/index.js new file mode 100644 index 0000000000000..d5a47844bb33a --- /dev/null +++ b/packages/editor/src/components/reusable-blocks-buttons/index.js @@ -0,0 +1,40 @@ +/** + * WordPress dependencies + */ +import { Fragment } from '@wordpress/element'; +import { __experimentalBlockSettingsMenuPluginsExtension } from '@wordpress/block-editor'; +import { withSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import ReusableBlockConvertButton from './reusable-block-convert-button'; +import ReusableBlockDeleteButton from './reusable-block-delete-button'; + +function ReusableBlocksButtons( { clientIds } ) { + return ( + <__experimentalBlockSettingsMenuPluginsExtension> + { ( { onClose } ) => ( + + + { clientIds.length === 1 && ( + + ) } + + ) } + + ); +} + +export default withSelect( ( select ) => { + const { getSelectedBlockClientIds } = select( 'core/block-editor' ); + return { + clientIds: getSelectedBlockClientIds(), + }; +} )( ReusableBlocksButtons ); diff --git a/packages/block-editor/src/components/block-settings-menu/reusable-block-convert-button.js b/packages/editor/src/components/reusable-blocks-buttons/reusable-block-convert-button.js similarity index 100% rename from packages/block-editor/src/components/block-settings-menu/reusable-block-convert-button.js rename to packages/editor/src/components/reusable-blocks-buttons/reusable-block-convert-button.js diff --git a/packages/block-editor/src/components/block-settings-menu/reusable-block-delete-button.js b/packages/editor/src/components/reusable-blocks-buttons/reusable-block-delete-button.js similarity index 100% rename from packages/block-editor/src/components/block-settings-menu/reusable-block-delete-button.js rename to packages/editor/src/components/reusable-blocks-buttons/reusable-block-delete-button.js diff --git a/packages/block-editor/src/components/block-settings-menu/test/__snapshots__/reusable-block-delete-button.js.snap b/packages/editor/src/components/reusable-blocks-buttons/test/__snapshots__/reusable-block-delete-button.js.snap similarity index 100% rename from packages/block-editor/src/components/block-settings-menu/test/__snapshots__/reusable-block-delete-button.js.snap rename to packages/editor/src/components/reusable-blocks-buttons/test/__snapshots__/reusable-block-delete-button.js.snap diff --git a/packages/block-editor/src/components/block-settings-menu/test/reusable-block-convert-button.js b/packages/editor/src/components/reusable-blocks-buttons/test/reusable-block-convert-button.js similarity index 100% rename from packages/block-editor/src/components/block-settings-menu/test/reusable-block-convert-button.js rename to packages/editor/src/components/reusable-blocks-buttons/test/reusable-block-convert-button.js diff --git a/packages/block-editor/src/components/block-settings-menu/test/reusable-block-delete-button.js b/packages/editor/src/components/reusable-blocks-buttons/test/reusable-block-delete-button.js similarity index 100% rename from packages/block-editor/src/components/block-settings-menu/test/reusable-block-delete-button.js rename to packages/editor/src/components/reusable-blocks-buttons/test/reusable-block-delete-button.js