From 5a98254888414520153c56f891a16b03e16a7da6 Mon Sep 17 00:00:00 2001 From: Jacopo Tomasone Date: Tue, 2 Mar 2021 11:08:06 +0000 Subject: [PATCH] Site Editor: Persistent List View (#28637) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert the List View dropdown into a persistent sidebar occupying the same interface skeleton slot as the Inserter (`secondarySidebar`). This change is currently experimental, and is only enabled in the Site Editor. Props @Addison-Stavlo ✨ Co-authored-by: James Koster --- .../src/components/block-navigation/block.js | 45 ++++++++-- .../components/block-navigation/context.js | 1 + .../components/block-navigation/dropdown.js | 18 +--- .../src/components/block-navigation/tree.js | 13 ++- .../src/navigation/use-block-navigator.js | 16 +--- .../specs/editor/blocks/columns.test.js | 2 +- .../specs/editor/blocks/cover.test.js | 2 +- .../block-hierarchy-navigation.test.js | 6 +- .../edit-site/src/components/editor/index.js | 63 ++++---------- .../src/components/editor/style.scss | 26 ------ .../edit-site/src/components/header/index.js | 27 +++++- .../components/keyboard-shortcuts/index.js | 38 +++++++- .../secondary-sidebar/inserter-sidebar.js | 43 +++++++++ .../secondary-sidebar/list-view-sidebar.js | 84 ++++++++++++++++++ .../components/secondary-sidebar/style.scss | 51 +++++++++++ packages/edit-site/src/store/actions.js | 13 +++ packages/edit-site/src/store/reducer.js | 33 ++++++- packages/edit-site/src/store/selectors.js | 11 +++ packages/edit-site/src/store/test/actions.js | 14 +++ packages/edit-site/src/store/test/reducer.js | 87 +++++++++++++++++++ .../edit-site/src/store/test/selectors.js | 12 +++ packages/edit-site/src/style.scss | 1 + packages/icons/src/index.js | 1 + packages/icons/src/library/list-view.js | 12 +++ 24 files changed, 492 insertions(+), 127 deletions(-) create mode 100644 packages/edit-site/src/components/secondary-sidebar/inserter-sidebar.js create mode 100644 packages/edit-site/src/components/secondary-sidebar/list-view-sidebar.js create mode 100644 packages/edit-site/src/components/secondary-sidebar/style.scss create mode 100644 packages/icons/src/library/list-view.js diff --git a/packages/block-editor/src/components/block-navigation/block.js b/packages/block-editor/src/components/block-navigation/block.js index 8d8b1a9d0db812..d191f692b77343 100644 --- a/packages/block-editor/src/components/block-navigation/block.js +++ b/packages/block-editor/src/components/block-navigation/block.js @@ -43,7 +43,6 @@ export default function BlockNavigationBlock( { } ) { const cellRef = useRef( null ); const [ isHovered, setIsHovered ] = useState( false ); - const [ isFocused, setIsFocused ] = useState( false ); const { clientId } = block; const { isDragging, blockParents } = useSelect( ( select ) => { @@ -63,38 +62,66 @@ export default function BlockNavigationBlock( { [ clientId ] ); - const { selectBlock: selectEditorBlock } = useDispatch( blockEditorStore ); + const { + selectBlock: selectEditorBlock, + toggleBlockHighlight, + } = useDispatch( blockEditorStore ); const hasSiblings = siblingBlockCount > 0; const hasRenderedMovers = showBlockMovers && hasSiblings; - const hasVisibleMovers = isHovered || isFocused; const moverCellClassName = classnames( 'block-editor-block-navigation-block__mover-cell', - { 'is-visible': hasVisibleMovers } + { 'is-visible': isHovered } ); const { __experimentalFeatures: withExperimentalFeatures, + __experimentalPersistentListViewFeatures: withExperimentalPersistentListViewFeatures, } = useBlockNavigationContext(); const blockNavigationBlockSettingsClassName = classnames( 'block-editor-block-navigation-block__menu-cell', - { 'is-visible': hasVisibleMovers } + { 'is-visible': isHovered } ); + + // If BlockNavigation has experimental features related to the Persistent List View, + // only focus the selected list item on mount; otherwise the list would always + // try to steal the focus from the editor canvas. + useEffect( () => { + if ( withExperimentalPersistentListViewFeatures && isSelected ) { + cellRef.current.focus(); + } + }, [] ); + + // If BlockNavigation has experimental features (such as drag and drop) enabled, + // leave the focus handling as it was before, to avoid accidental regressions. useEffect( () => { if ( withExperimentalFeatures && isSelected ) { cellRef.current.focus(); } }, [ withExperimentalFeatures, isSelected ] ); + const highlightBlock = withExperimentalPersistentListViewFeatures + ? toggleBlockHighlight + : () => {}; + + const onMouseEnter = () => { + setIsHovered( true ); + highlightBlock( clientId, true ); + }; + const onMouseLeave = () => { + setIsHovered( false ); + highlightBlock( clientId, false ); + }; + return ( setIsHovered( true ) } - onMouseLeave={ () => setIsHovered( false ) } - onFocus={ () => setIsFocused( true ) } - onBlur={ () => setIsFocused( false ) } + onMouseEnter={ onMouseEnter } + onMouseLeave={ onMouseLeave } + onFocus={ onMouseEnter } + onBlur={ onMouseLeave } level={ level } position={ position } rowCount={ rowCount } diff --git a/packages/block-editor/src/components/block-navigation/context.js b/packages/block-editor/src/components/block-navigation/context.js index 1ed2527d1916fc..85cde846a826a5 100644 --- a/packages/block-editor/src/components/block-navigation/context.js +++ b/packages/block-editor/src/components/block-navigation/context.js @@ -5,6 +5,7 @@ import { createContext, useContext } from '@wordpress/element'; export const BlockNavigationContext = createContext( { __experimentalFeatures: false, + __experimentalPersistentListViewFeatures: false, } ); export const useBlockNavigationContext = () => diff --git a/packages/block-editor/src/components/block-navigation/dropdown.js b/packages/block-editor/src/components/block-navigation/dropdown.js index c639078f776ebb..b72d879d6762e4 100644 --- a/packages/block-editor/src/components/block-navigation/dropdown.js +++ b/packages/block-editor/src/components/block-navigation/dropdown.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { Button, Dropdown, SVG, Path } from '@wordpress/components'; +import { Button, Dropdown } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { @@ -9,6 +9,7 @@ import { store as keyboardShortcutsStore, } from '@wordpress/keyboard-shortcuts'; import { useCallback, forwardRef } from '@wordpress/element'; +import { listView } from '@wordpress/icons'; /** * Internal dependencies @@ -16,17 +17,6 @@ import { useCallback, forwardRef } from '@wordpress/element'; import BlockNavigation from './'; import { store as blockEditorStore } from '../../store'; -const MenuIcon = ( - - - -); - function BlockNavigationDropdownToggle( { isEnabled, onToggle, @@ -54,12 +44,12 @@ function BlockNavigationDropdownToggle( {