Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Site Editor: Persistent List View #28637

Merged
merged 34 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
cfc67aa
Move the Inserter into its own component for readability
Copons Feb 1, 2021
a554ad6
Also move the styles
Copons Feb 1, 2021
2fb3657
Duplicate the inserter behaviour into a new secondary sidebar
Copons Feb 1, 2021
994f517
Use BlockNavigationTree in the new sidebar
Copons Feb 1, 2021
4a55234
Create a new navigationMenu icon to be reused across the editors
Copons Feb 1, 2021
ec3bc33
Style the block navigation sidebar
Copons Feb 2, 2021
303f0ed
Add a keyboard shortcut to toggle the block navigation sidebar
Copons Feb 2, 2021
1b3393a
Focus first element on mount
Copons Feb 2, 2021
5b20267
Add highlight on hover/focus
Copons Feb 3, 2021
9a73565
Simplify hover handling
Copons Feb 3, 2021
b356be4
Rename the sidebar to "List View"
Copons Feb 3, 2021
d89120c
Replace hardcoded store string
Copons Feb 4, 2021
80afa89
Styles
jameskoster Feb 4, 2021
ec80e17
radius
jameskoster Feb 4, 2021
78f6158
Move the list item border radius and box shadow overrides to the pers…
Copons Feb 5, 2021
ccadb66
Fix tests for new "List view" label
Copons Feb 5, 2021
7c666f7
Revert "Move the list item border radius and box shadow overrides to …
Copons Feb 8, 2021
9e0342b
Revert "radius"
Copons Feb 8, 2021
4555468
Revert "Styles"
Copons Feb 8, 2021
a4e8509
Experimental: Try the same hover/focus/select colors for both blocks …
Copons Feb 19, 2021
4f04a03
Focus selected list item on mount
Copons Feb 23, 2021
71affa4
Remove experimental style changes
Copons Feb 24, 2021
25fcd2e
Add inline docs to the new focus hook
Copons Feb 24, 2021
1e100b4
Code cleanup
Copons Feb 24, 2021
874839a
Use the block navigation context to handle experimental persistent li…
Copons Feb 24, 2021
a6a774d
Fix secondary sidebar hiding the editor on small screens
Copons Feb 25, 2021
4679b63
Consolidate duplicate styles
Copons Feb 25, 2021
5116e39
Add useDialog hook to handle close on ESC
Copons Feb 25, 2021
7dcdf32
Properly handle close on esc and focus return
Copons Feb 25, 2021
82e45b5
Add tests for the new listViewPanel reducer
Copons Feb 25, 2021
a584093
Remove the constrained tabbing
Copons Feb 25, 2021
db4ae35
Make the List View as wide as the Inserter
Copons Feb 26, 2021
9b4eba4
Fix typo
Copons Feb 26, 2021
e907eab
Fix focus handling
Copons Mar 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions packages/block-editor/src/components/block-navigation/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) => {
Expand All @@ -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 (
<BlockNavigationLeaf
className={ classnames( {
'is-selected': isSelected,
'is-dragging': isDragging,
} ) }
onMouseEnter={ () => 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 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createContext, useContext } from '@wordpress/element';

export const BlockNavigationContext = createContext( {
__experimentalFeatures: false,
__experimentalPersistentListViewFeatures: false,
} );

export const useBlockNavigationContext = () =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
/**
* 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 {
useShortcut,
store as keyboardShortcutsStore,
} from '@wordpress/keyboard-shortcuts';
import { useCallback, forwardRef } from '@wordpress/element';
import { listView } from '@wordpress/icons';

/**
* Internal dependencies
*/
import BlockNavigation from './';
import { store as blockEditorStore } from '../../store';

const MenuIcon = (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
>
<Path d="M13.8 5.2H3v1.5h10.8V5.2zm-3.6 12v1.5H21v-1.5H10.2zm7.2-6H6.6v1.5h10.8v-1.5z" />
</SVG>
);

function BlockNavigationDropdownToggle( {
isEnabled,
onToggle,
Expand Down Expand Up @@ -54,12 +44,12 @@ function BlockNavigationDropdownToggle( {
<Button
{ ...props }
ref={ innerRef }
icon={ MenuIcon }
icon={ listView }
aria-expanded={ isOpen }
aria-haspopup="true"
onClick={ isEnabled ? onToggle : undefined }
/* translators: button label text should, if possible, be under 16 characters. */
label={ __( 'Outline' ) }
label={ __( 'List view' ) }
className="block-editor-block-navigation"
shortcut={ shortcut }
aria-disabled={ ! isEnabled }
Expand Down
13 changes: 10 additions & 3 deletions packages/block-editor/src/components/block-navigation/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ import useBlockNavigationDropZone from './use-block-navigation-drop-zone';
* recursive component (it renders itself), so this ensures TreeGrid is only
* present at the very top of the navigation grid.
*
* @param {Object} props Components props.
* @param {Object} props.__experimentalFeatures Object used in context provider.
* @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.
*/
export default function BlockNavigationTree( {
__experimentalFeatures,
__experimentalPersistentListViewFeatures,
...props
} ) {
const treeGridRef = useRef();
Expand All @@ -35,9 +37,14 @@ export default function BlockNavigationTree( {
const contextValue = useMemo(
() => ( {
__experimentalFeatures,
__experimentalPersistentListViewFeatures,
blockDropTarget,
} ),
[ __experimentalFeatures, blockDropTarget ]
[
__experimentalFeatures,
__experimentalPersistentListViewFeatures,
blockDropTarget,
]
);

return (
Expand Down
16 changes: 3 additions & 13 deletions packages/block-library/src/navigation/use-block-navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,15 @@
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import { ToolbarButton, SVG, Path, Modal } from '@wordpress/components';
import { ToolbarButton, Modal } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { listView } from '@wordpress/icons';

/**
* Internal dependencies
*/
import BlockNavigationList from './block-navigation-list';

const NavigatorIcon = (
<SVG
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="24"
height="24"
>
<Path d="M13.8 5.2H3v1.5h10.8V5.2zm-3.6 12v1.5H21v-1.5H10.2zm7.2-6H6.6v1.5h10.8v-1.5z" />
</SVG>
);

export default function useBlockNavigator( clientId, __experimentalFeatures ) {
const [ isNavigationListOpen, setIsNavigationListOpen ] = useState( false );

Expand All @@ -29,7 +19,7 @@ export default function useBlockNavigator( clientId, __experimentalFeatures ) {
className="components-toolbar__control"
label={ __( 'Open block navigator' ) }
onClick={ () => setIsNavigationListOpen( true ) }
icon={ NavigatorIcon }
icon={ listView }
/>
);

Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-tests/specs/editor/blocks/columns.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe( 'Columns', () => {
await insertBlock( 'Columns' );
await closeGlobalBlockInserter();
await page.click( '[aria-label="Two columns; equal split"]' );
await page.click( '[aria-label="Outline"]' );
await page.click( '[aria-label="List view"]' );
const columnBlockMenuItem = (
await page.$x(
'//button[contains(concat(" ", @class, " "), " block-editor-block-navigation-block-select-button ")][text()="Column"]'
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e-tests/specs/editor/blocks/cover.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe( 'Cover', () => {
);

// Select the cover block.By default the child paragraph gets selected.
await page.click( 'button[aria-label="Outline"]' );
await page.click( 'button[aria-label="List view"]' );
await page.click(
'.block-editor-block-navigation-block__contents-container button'
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe( 'Navigating the block hierarchy', () => {
await page.keyboard.type( 'First column' );

// Navigate to the columns blocks.
await page.click( '[aria-label="Outline"]' );
await page.click( '[aria-label="List view"]' );
const columnsBlockMenuItem = (
await page.$x(
"//button[contains(@class,'block-editor-block-navigation-block-select-button') and contains(text(), 'Columns')]"
Expand All @@ -69,7 +69,7 @@ describe( 'Navigating the block hierarchy', () => {
await page.keyboard.type( '3' );

// Navigate to the last column block.
await page.click( '[aria-label="Outline"]' );
await page.click( '[aria-label="List view"]' );
const lastColumnsBlockMenuItem = (
await page.$x(
"//button[contains(@class,'block-editor-block-navigation-block-select-button') and contains(text(), 'Column')]"
Expand Down Expand Up @@ -175,7 +175,7 @@ describe( 'Navigating the block hierarchy', () => {
await page.click( '.editor-post-title' );

// Try selecting the group block using the Outline
await page.click( '[aria-label="Outline"]' );
await page.click( '[aria-label="List view"]' );
const groupMenuItem = (
await page.$x(
"//button[contains(@class,'block-editor-block-navigation-block-select-button') and contains(text(), 'Group')]"
Expand Down
63 changes: 17 additions & 46 deletions packages/edit-site/src/components/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ import {
Button,
} from '@wordpress/components';
import { EntityProvider } from '@wordpress/core-data';
import {
BlockContextProvider,
BlockBreadcrumb,
__experimentalLibrary as Library,
} from '@wordpress/block-editor';
import { BlockContextProvider, BlockBreadcrumb } from '@wordpress/block-editor';
import {
FullscreenMode,
InterfaceSkeleton,
Expand All @@ -24,11 +20,6 @@ import {
import { EntitiesSavedStates, UnsavedChangesWarning } from '@wordpress/editor';
import { __ } from '@wordpress/i18n';
import { PluginArea } from '@wordpress/plugins';
import { close } from '@wordpress/icons';
import {
useViewportMatch,
__experimentalUseDialog as useDialog,
} from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -41,6 +32,8 @@ import KeyboardShortcuts from '../keyboard-shortcuts';
import GlobalStylesProvider from './global-styles-provider';
import NavigationSidebar from '../navigation-sidebar';
import URLQueryController from '../url-query-controller';
import InserterSidebar from '../secondary-sidebar/inserter-sidebar';
import ListViewSidebar from '../secondary-sidebar/list-view-sidebar';
import { store as editSiteStore } from '../../store';

const interfaceLabels = {
Expand All @@ -52,6 +45,7 @@ function Editor( { initialSettings } ) {
const {
isFullscreenActive,
isInserterOpen,
isListViewOpen,
sidebarIsOpened,
settings,
entityId,
Expand All @@ -63,6 +57,7 @@ function Editor( { initialSettings } ) {
const {
isFeatureActive,
isInserterOpened,
isListViewOpened,
getSettings,
getEditedPostType,
getEditedPostId,
Expand All @@ -79,6 +74,7 @@ function Editor( { initialSettings } ) {
// The currently selected entity to display. Typically template or template part.
return {
isInserterOpen: isInserterOpened(),
isListViewOpen: isListViewOpened(),
isFullscreenActive: isFeatureActive( 'fullscreenMode' ),
sidebarIsOpened: !! select(
interfaceStore
Expand Down Expand Up @@ -155,17 +151,21 @@ function Editor( { initialSettings } ) {
}
}, [ isNavigationOpen ] );

const isMobile = useViewportMatch( 'medium', '<' );

const [ inserterDialogRef, inserterDialogProps ] = useDialog( {
onClose: () => setIsInserterOpened( false ),
} );

// Don't render the Editor until the settings are set and loaded
if ( ! settings?.siteUrl ) {
return null;
}

const secondarySidebar = () => {
if ( isInserterOpen ) {
return <InserterSidebar />;
}
if ( isListViewOpen ) {
return <ListViewSidebar />;
}
return null;
};

return (
<>
<URLQueryController />
Expand Down Expand Up @@ -197,36 +197,7 @@ function Editor( { initialSettings } ) {
<InterfaceSkeleton
labels={ interfaceLabels }
drawer={ <NavigationSidebar /> }
secondarySidebar={
isInserterOpen ? (
<div
ref={
inserterDialogRef
}
{ ...inserterDialogProps }
className="edit-site-editor__inserter-panel"
>
<div className="edit-site-editor__inserter-panel-header">
<Button
icon={ close }
onClick={ () =>
setIsInserterOpened(
false
)
}
/>
</div>
<div className="edit-site-editor__inserter-panel-content">
<Library
showInserterHelpPanel
shouldFocusBlock={
isMobile
}
/>
</div>
</div>
) : null
Copons marked this conversation as resolved.
Show resolved Hide resolved
}
secondarySidebar={ secondarySidebar() }
sidebar={
sidebarIsOpened && (
<ComplementaryArea.Slot scope="core/edit-site" />
Expand Down
Loading