From 688c500a51b9ffe3ea072e9fcc469d896d72485f Mon Sep 17 00:00:00 2001 From: Copons Date: Mon, 15 Mar 2021 17:05:27 +0000 Subject: [PATCH 1/6] Enable multi-selected support for the Persistent List View --- .../src/components/block-navigation/block.js | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/block-editor/src/components/block-navigation/block.js b/packages/block-editor/src/components/block-navigation/block.js index ea4b59051e0e5b..b9b836a5bca6cc 100644 --- a/packages/block-editor/src/components/block-navigation/block.js +++ b/packages/block-editor/src/components/block-navigation/block.js @@ -46,12 +46,13 @@ export default function BlockNavigationBlock( { const cellRef = useRef( null ); const [ isHovered, setIsHovered ] = useState( false ); const { clientId } = block; - const { isDragging, blockParents } = useSelect( + const { isDragging, blockParents, isMultiSelected } = useSelect( ( select ) => { const { isBlockBeingDragged, isAncestorBeingDragged, getBlockParents, + isBlockMultiSelected, } = select( blockEditorStore ); return { @@ -59,6 +60,7 @@ export default function BlockNavigationBlock( { isBlockBeingDragged( clientId ) || isAncestorBeingDragged( clientId ), blockParents: getBlockParents( clientId ), + isMultiSelected: isBlockMultiSelected( clientId ), }; }, [ clientId ] @@ -114,18 +116,21 @@ export default function BlockNavigationBlock( { highlightBlock( clientId, false ); }; + const classes = classnames( { + 'is-selected': + isSelected || + ( withExperimentalPersistentListViewFeatures && isMultiSelected ), + 'is-branch-selected': + withExperimentalPersistentListViewFeatures && isBranchSelected, + 'is-last-of-selected-branch': + withExperimentalPersistentListViewFeatures && + isLastOfSelectedBranch, + 'is-dragging': isDragging, + } ); + return ( Date: Tue, 16 Mar 2021 18:45:21 +0000 Subject: [PATCH 2/6] Add native support for multi-selection --- .../src/components/block-navigation/block.js | 8 ++------ .../src/components/block-navigation/branch.js | 9 ++++++--- .../src/components/block-navigation/index.js | 18 +++++++++++------- .../src/components/block-navigation/utils.js | 19 +++++++++++++++++++ .../secondary-sidebar/list-view-sidebar.js | 6 +++--- 5 files changed, 41 insertions(+), 19 deletions(-) diff --git a/packages/block-editor/src/components/block-navigation/block.js b/packages/block-editor/src/components/block-navigation/block.js index b9b836a5bca6cc..42e970cc7c0762 100644 --- a/packages/block-editor/src/components/block-navigation/block.js +++ b/packages/block-editor/src/components/block-navigation/block.js @@ -46,13 +46,12 @@ export default function BlockNavigationBlock( { const cellRef = useRef( null ); const [ isHovered, setIsHovered ] = useState( false ); const { clientId } = block; - const { isDragging, blockParents, isMultiSelected } = useSelect( + const { isDragging, blockParents } = useSelect( ( select ) => { const { isBlockBeingDragged, isAncestorBeingDragged, getBlockParents, - isBlockMultiSelected, } = select( blockEditorStore ); return { @@ -60,7 +59,6 @@ export default function BlockNavigationBlock( { isBlockBeingDragged( clientId ) || isAncestorBeingDragged( clientId ), blockParents: getBlockParents( clientId ), - isMultiSelected: isBlockMultiSelected( clientId ), }; }, [ clientId ] @@ -117,9 +115,7 @@ export default function BlockNavigationBlock( { }; const classes = classnames( { - 'is-selected': - isSelected || - ( withExperimentalPersistentListViewFeatures && isMultiSelected ), + 'is-selected': isSelected, 'is-branch-selected': withExperimentalPersistentListViewFeatures && isBranchSelected, 'is-last-of-selected-branch': diff --git a/packages/block-editor/src/components/block-navigation/branch.js b/packages/block-editor/src/components/block-navigation/branch.js index 17fcf1ad64a235..de9f205b0af20a 100644 --- a/packages/block-editor/src/components/block-navigation/branch.js +++ b/packages/block-editor/src/components/block-navigation/branch.js @@ -13,7 +13,7 @@ import { Fragment } from '@wordpress/element'; */ import BlockNavigationBlock from './block'; import BlockNavigationAppender from './appender'; - +import { isClientIdSelected } from './utils'; export default function BlockNavigationBranch( props ) { const { blocks, @@ -35,7 +35,7 @@ export default function BlockNavigationBranch( props ) { const itemHasAppender = ( parentClientId ) => showAppender && ! isTreeRoot && - selectedBlockClientId === parentClientId; + isClientIdSelected( parentClientId, selectedBlockClientId ); const hasAppender = itemHasAppender( parentBlockClientId ); // Add +1 to the rowCount to take the block appender into account. const blockCount = filteredBlocks.length; @@ -57,7 +57,10 @@ export default function BlockNavigationBranch( props ) { const hasNestedAppender = itemHasAppender( clientId ); const hasNestedBranch = hasNestedBlocks || hasNestedAppender; - const isSelected = selectedBlockClientId === clientId; + const isSelected = isClientIdSelected( + clientId, + selectedBlockClientId + ); const isSelectedBranch = isBranchSelected || ( isSelected && hasNestedBranch ); diff --git a/packages/block-editor/src/components/block-navigation/index.js b/packages/block-editor/src/components/block-navigation/index.js index f6121bac8c6fc5..e58618d0122354 100644 --- a/packages/block-editor/src/components/block-navigation/index.js +++ b/packages/block-editor/src/components/block-navigation/index.js @@ -1,7 +1,7 @@ /** * External dependencies */ -import { noop } from 'lodash'; +import { isArray, noop } from 'lodash'; /** * WordPress dependencies @@ -13,6 +13,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import BlockNavigationTree from './tree'; +import { isClientIdSelected } from './utils'; import { store as blockEditorStore } from '../../store'; export default function BlockNavigation( { @@ -30,11 +31,14 @@ export default function BlockNavigation( { const _selectedBlockClientId = getSelectedBlockClientId(); const _rootBlocks = __unstableGetClientIdsTree(); - const _rootBlock = _selectedBlockClientId - ? __unstableGetClientIdWithClientIdsTree( - getBlockHierarchyRootClientId( _selectedBlockClientId ) - ) - : null; + const _rootBlock = + selectedBlockClientId && ! isArray( selectedBlockClientId ) + ? __unstableGetClientIdWithClientIdsTree( + getBlockHierarchyRootClientId( + _selectedBlockClientId + ) + ) + : null; return { rootBlock: _rootBlock, @@ -56,7 +60,7 @@ export default function BlockNavigation( { const hasHierarchy = rootBlock && - ( rootBlock.clientId !== selectedBlockClientId || + ( isClientIdSelected( rootBlock.clientId, selectedBlockClientId ) || ( rootBlock.innerBlocks && rootBlock.innerBlocks.length !== 0 ) ); return ( diff --git a/packages/block-editor/src/components/block-navigation/utils.js b/packages/block-editor/src/components/block-navigation/utils.js index 51d3a015dc81bb..1ff674ecc0eeb2 100644 --- a/packages/block-editor/src/components/block-navigation/utils.js +++ b/packages/block-editor/src/components/block-navigation/utils.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import { isArray } from 'lodash'; + /** * WordPress dependencies */ @@ -11,3 +16,17 @@ export const getBlockPositionDescription = ( position, siblingCount, level ) => siblingCount, level ); + +/** + * Returns true if the client ID occurs within the block selection or multi-selection, + * or false otherwise. + * + * @param {string} clientId Block client ID. + * @param {string|string[]} selectedBlockClientId Selected block client ID, or an array of multi-selected blocks client IDs. + * + * @return {boolean} Whether the block is in multi-selection set. + */ +export const isClientIdSelected = ( clientId, selectedBlockClientId ) => + isArray( selectedBlockClientId ) && selectedBlockClientId.length + ? selectedBlockClientId.indexOf( clientId ) !== -1 + : selectedBlockClientId === clientId; diff --git a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js index efc93f8a957869..c2ab00ca765b1c 100644 --- a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js +++ b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js @@ -23,13 +23,13 @@ import { ESCAPE } from '@wordpress/keycodes'; import { store as editSiteStore } from '../../store'; export default function ListViewSidebar() { - const { clientIdsTree, selectedBlockClientId } = useSelect( ( select ) => { + const { clientIdsTree, selectedBlockClientIds } = useSelect( ( select ) => { const { __unstableGetClientIdsTree, getSelectedBlockClientId } = select( blockEditorStore ); return { clientIdsTree: __unstableGetClientIdsTree(), - selectedBlockClientId: getSelectedBlockClientId(), + selectedBlockClientIds: getSelectedBlockClientId(), }; } ); const { setIsListViewOpened } = useDispatch( editSiteStore ); @@ -74,7 +74,7 @@ export default function ListViewSidebar() { From ed278bad6d76430f6c2a381d65bbc59627dc46af Mon Sep 17 00:00:00 2001 From: Copons Date: Fri, 19 Mar 2021 10:23:28 +0000 Subject: [PATCH 3/6] Fix typo --- packages/block-editor/src/components/block-navigation/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-navigation/index.js b/packages/block-editor/src/components/block-navigation/index.js index e58618d0122354..66145ee0936844 100644 --- a/packages/block-editor/src/components/block-navigation/index.js +++ b/packages/block-editor/src/components/block-navigation/index.js @@ -60,7 +60,7 @@ export default function BlockNavigation( { const hasHierarchy = rootBlock && - ( isClientIdSelected( rootBlock.clientId, selectedBlockClientId ) || + ( ! isClientIdSelected( rootBlock.clientId, selectedBlockClientId ) || ( rootBlock.innerBlocks && rootBlock.innerBlocks.length !== 0 ) ); return ( From 9aba7a2e8a0c6419ace53f170153a6dc9c5dfd6d Mon Sep 17 00:00:00 2001 From: Copons Date: Fri, 19 Mar 2021 17:12:55 +0000 Subject: [PATCH 4/6] Rename the prop to plural, and deprecate singular --- .../src/components/block-navigation/branch.js | 10 ++++--- .../src/components/block-navigation/index.js | 2 +- .../src/components/block-navigation/tree.js | 28 +++++++++++++++++-- .../src/navigation/block-navigation-list.js | 2 +- .../secondary-sidebar/list-view-sidebar.js | 2 +- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/block-navigation/branch.js b/packages/block-editor/src/components/block-navigation/branch.js index de9f205b0af20a..6b2c766f2a4d4f 100644 --- a/packages/block-editor/src/components/block-navigation/branch.js +++ b/packages/block-editor/src/components/block-navigation/branch.js @@ -18,7 +18,7 @@ export default function BlockNavigationBranch( props ) { const { blocks, selectBlock, - selectedBlockClientId, + selectedBlockClientIds, showAppender, showBlockMovers, showNestedBlocks, @@ -35,7 +35,7 @@ export default function BlockNavigationBranch( props ) { const itemHasAppender = ( parentClientId ) => showAppender && ! isTreeRoot && - isClientIdSelected( parentClientId, selectedBlockClientId ); + isClientIdSelected( parentClientId, selectedBlockClientIds ); const hasAppender = itemHasAppender( parentBlockClientId ); // Add +1 to the rowCount to take the block appender into account. const blockCount = filteredBlocks.length; @@ -59,7 +59,7 @@ export default function BlockNavigationBranch( props ) { const isSelected = isClientIdSelected( clientId, - selectedBlockClientId + selectedBlockClientIds ); const isSelectedBranch = isBranchSelected || ( isSelected && hasNestedBranch ); @@ -90,7 +90,9 @@ export default function BlockNavigationBranch( props ) { { hasNestedBranch && ( - + ); diff --git a/packages/block-library/src/navigation/block-navigation-list.js b/packages/block-library/src/navigation/block-navigation-list.js index 43dfc64518d676..057c4e6396b049 100644 --- a/packages/block-library/src/navigation/block-navigation-list.js +++ b/packages/block-library/src/navigation/block-navigation-list.js @@ -31,7 +31,7 @@ export default function BlockNavigationList( { return ( <__experimentalBlockNavigationTree blocks={ blocks } - selectedBlockClientId={ selectedBlockClientId } + selectedBlockClientIds={ [ selectedBlockClientId ] } selectBlock={ selectBlock } __experimentalFeatures={ __experimentalFeatures } showNestedBlocks diff --git a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js index c2ab00ca765b1c..3fcd84c5eae612 100644 --- a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js +++ b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js @@ -74,7 +74,7 @@ export default function ListViewSidebar() { From f2fdc47c8a08e8e0ca8116b6d5dd432595b5b76b Mon Sep 17 00:00:00 2001 From: Copons Date: Mon, 22 Mar 2021 11:28:25 +0000 Subject: [PATCH 5/6] Remove the deprecation and force the prop name change --- .../src/components/block-navigation/tree.js | 27 +------------------ .../src/components/block-navigation/utils.js | 12 ++++----- 2 files changed, 7 insertions(+), 32 deletions(-) diff --git a/packages/block-editor/src/components/block-navigation/tree.js b/packages/block-editor/src/components/block-navigation/tree.js index 3be2d172c05808..e159c30973903b 100644 --- a/packages/block-editor/src/components/block-navigation/tree.js +++ b/packages/block-editor/src/components/block-navigation/tree.js @@ -3,7 +3,6 @@ */ import { __experimentalTreeGrid as TreeGrid } from '@wordpress/components'; -import deprecated from '@wordpress/deprecated'; import { useMemo, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** @@ -21,14 +20,10 @@ import useBlockNavigationDropZone from './use-block-navigation-drop-zone'; * @param {Object} props Components props. * @param {boolean} props.__experimentalFeatures Flag to enable experimental features. * @param {boolean} props.__experimentalPersistentListViewFeatures Flag to enable features for the Persistent List View experiment. - * @param {string} props.selectedBlockClientId Deprecated. See props.selectedBlockClientIds. - * @param {Array} props.selectedBlockClientIds List of selected block client IDs. */ export default function BlockNavigationTree( { __experimentalFeatures, __experimentalPersistentListViewFeatures, - selectedBlockClientId, - selectedBlockClientIds, ...props } ) { const treeGridRef = useRef(); @@ -51,26 +46,6 @@ export default function BlockNavigationTree( { ] ); - // Deprecate selectedBlockClientId - if ( selectedBlockClientId ) { - deprecated( - 'selectedBlockClientId (singular) prop of the BlockNavigationTree component', - { - alternative: - 'selectedBlockClientIds (renamed to plural) of the BlockNavigationTree component', - hint: 'The renamed prop is an array', - } - ); - } - // Convert selectedBlockClientId to selectedBlockClientIds for backward compatibility. - const updatedProps = { - ...props, - selectedBlockClientIds: - selectedBlockClientId && ! selectedBlockClientIds - ? [ selectedBlockClientId ] - : selectedBlockClientIds, - }; - return ( - + ); diff --git a/packages/block-editor/src/components/block-navigation/utils.js b/packages/block-editor/src/components/block-navigation/utils.js index 1ff674ecc0eeb2..50bb561e42a8a6 100644 --- a/packages/block-editor/src/components/block-navigation/utils.js +++ b/packages/block-editor/src/components/block-navigation/utils.js @@ -21,12 +21,12 @@ export const getBlockPositionDescription = ( position, siblingCount, level ) => * Returns true if the client ID occurs within the block selection or multi-selection, * or false otherwise. * - * @param {string} clientId Block client ID. - * @param {string|string[]} selectedBlockClientId Selected block client ID, or an array of multi-selected blocks client IDs. + * @param {string} clientId Block client ID. + * @param {string|string[]} selectedBlockClientIds Selected block client ID, or an array of multi-selected blocks client IDs. * * @return {boolean} Whether the block is in multi-selection set. */ -export const isClientIdSelected = ( clientId, selectedBlockClientId ) => - isArray( selectedBlockClientId ) && selectedBlockClientId.length - ? selectedBlockClientId.indexOf( clientId ) !== -1 - : selectedBlockClientId === clientId; +export const isClientIdSelected = ( clientId, selectedBlockClientIds ) => + isArray( selectedBlockClientIds ) && selectedBlockClientIds.length + ? selectedBlockClientIds.indexOf( clientId ) !== -1 + : selectedBlockClientIds === clientId; From c89ff13a138919cb777e3de98c9596e8eb6fb450 Mon Sep 17 00:00:00 2001 From: Copons Date: Mon, 22 Mar 2021 12:17:48 +0000 Subject: [PATCH 6/6] Sort out a rebase error --- .../components/secondary-sidebar/list-view-sidebar.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js index 3fcd84c5eae612..0dd3d956684e29 100644 --- a/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js +++ b/packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js @@ -24,12 +24,13 @@ import { store as editSiteStore } from '../../store'; export default function ListViewSidebar() { const { clientIdsTree, selectedBlockClientIds } = useSelect( ( select ) => { - const { __unstableGetClientIdsTree, getSelectedBlockClientId } = select( - blockEditorStore - ); + const { + __unstableGetClientIdsTree, + getSelectedBlockClientIds, + } = select( blockEditorStore ); return { clientIdsTree: __unstableGetClientIdsTree(), - selectedBlockClientIds: getSelectedBlockClientId(), + selectedBlockClientIds: getSelectedBlockClientIds(), }; } ); const { setIsListViewOpened } = useDispatch( editSiteStore );