From 1a11f0753c20780740c0c434bdd6fbe7f3ade1c7 Mon Sep 17 00:00:00 2001 From: Jarda Snajdr Date: Wed, 17 Apr 2024 15:12:13 +0200 Subject: [PATCH] Site Editor: create router adapter for sidebar (#60466) * Site Editor: create router adapter for sidebar * Dissolve the Sidebar component, put items into areas.sidebar * Remove unused SidebarNavigationScreenNavigationItem * Eliminate usages of useNavigator() * Eliminate NavigatorButton from SidebarNavigationItem * Remove NavigatorProvider and NavigatorScreen * edit-site no longer needs path-to-regexp * Animation when navigating forward/backward * Sidebar animation with motion.div, basic focus mgmt * Add id attr to SidebarNavigationItem * Separate module for SidebarContent * Fix focusing when going back * Don't focus on initial render * Keep focusSelector across multiple back navigations --- .../edit-site/src/components/layout/index.js | 11 +- .../edit-site/src/components/layout/router.js | 85 +++++++-- .../sidebar-navigation-item/index.js | 29 +++ .../index.js | 13 +- .../sidebar-navigation-screen-main/index.js | 34 ++-- .../index.js | 59 ------ .../index.js | 11 +- .../use-navigation-menu-handlers.js | 16 +- .../leaf-more-menu.js | 9 +- .../sidebar-navigation-screen-page/index.js | 7 +- .../index.js | 15 +- .../index.js | 15 +- .../index.js | 9 +- .../sidebar-navigation-screen/index.js | 41 +++-- .../edit-site/src/components/sidebar/index.js | 173 +++++++----------- .../src/components/sidebar/style.scss | 2 + .../use-sync-path-with-url.js | 147 --------------- 17 files changed, 264 insertions(+), 412 deletions(-) delete mode 100644 packages/edit-site/src/components/sidebar-navigation-screen-navigation-item/index.js delete mode 100644 packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js diff --git a/packages/edit-site/src/components/layout/index.js b/packages/edit-site/src/components/layout/index.js index 51f55302f16e7..9ddeed49981be 100644 --- a/packages/edit-site/src/components/layout/index.js +++ b/packages/edit-site/src/components/layout/index.js @@ -35,7 +35,6 @@ import { privateApis as editorPrivateApis } from '@wordpress/editor'; /** * Internal dependencies */ -import Sidebar from '../sidebar'; import ErrorBoundary from '../error-boundary'; import { store as editSiteStore } from '../../store'; import useInitEditedEntityFromURL from '../sync-state-with-url/use-init-edited-entity-from-url'; @@ -51,6 +50,8 @@ import { useEditModeCommands } from '../../hooks/commands/use-edit-mode-commands import { useIsSiteEditorLoading } from './hooks'; import useLayoutAreas from './router'; import useMovingAnimation from './animation'; +import SidebarContent from '../sidebar'; +import SaveHub from '../save-hub'; const { useCommands } = unlock( coreCommandsPrivateApis ); const { useCommandContext } = unlock( commandsPrivateApis ); @@ -224,8 +225,7 @@ export default function Layout() { The NavigableRegion must always be rendered and not use `inert` otherwise `useNavigateRegions` will fail. */ } - { ( ! isMobileViewport || - ( isMobileViewport && ! areas.mobile ) ) && ( + { ( ! isMobileViewport || ! areas.mobile ) && ( - + + { areas.sidebar } + + ) } diff --git a/packages/edit-site/src/components/layout/router.js b/packages/edit-site/src/components/layout/router.js index 3482c122c3630..634a5663bf163 100644 --- a/packages/edit-site/src/components/layout/router.js +++ b/packages/edit-site/src/components/layout/router.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { __ } from '@wordpress/i18n'; /** * Internal dependencies @@ -12,7 +13,17 @@ import Editor from '../editor'; import PagePages from '../page-pages'; import PagePatterns from '../page-patterns'; import PageTemplatesTemplateParts from '../page-templates-template-parts'; - +import SidebarNavigationScreen from '../sidebar-navigation-screen'; +import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles'; +import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; +import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; +import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page'; +import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; +import SidebarNavigationScreenTemplate from '../sidebar-navigation-screen-template'; +import SidebarNavigationScreenPattern from '../sidebar-navigation-screen-pattern'; +import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; +import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; +import DataViewsSidebarContent from '../sidebar-dataviews'; import { TEMPLATE_POST_TYPE, TEMPLATE_PART_POST_TYPE, @@ -29,19 +40,24 @@ export default function useLayoutAreas() { // Note: Since "sidebar" is not yet supported here, // returning undefined from "mobile" means show the sidebar. - // Regular page + // Page list if ( path === '/page' ) { const isListLayout = layout === 'list' || ! layout; return { key: 'pages-list', areas: { + sidebar: ( + } + /> + ), content: , preview: isListLayout && ( history.push( { - path, postType: 'page', postId, canvas: 'edit', @@ -64,14 +80,24 @@ export default function useLayoutAreas() { // Regular other post types if ( postType && postId ) { + let sidebar; + if ( postType === 'wp_template_part' || postType === 'wp_block' ) { + sidebar = ; + } else if ( postType === 'wp_template' ) { + sidebar = ; + } else if ( postType === 'page' ) { + sidebar = ; + } else { + sidebar = ; + } return { key: 'page', areas: { + sidebar, preview: , - mobile: - canvas === 'edit' ? ( - - ) : undefined, + mobile: canvas === 'edit' && ( + + ), }, }; } @@ -82,6 +108,11 @@ export default function useLayoutAreas() { return { key: 'templates-list', areas: { + sidebar: postId ? ( + + ) : ( + + ), content: ( + ), content: ( , content: , mobile: , }, }; } + // Styles + if ( path === '/wp_global_styles' ) { + return { + key: 'styles', + areas: { + sidebar: , + preview: , + mobile: canvas === 'edit' && ( + + ), + }, + }; + } + + // Navigation + if ( path === '/navigation' ) { + return { + key: 'styles', + areas: { + sidebar: , + preview: , + mobile: canvas === 'edit' && ( + + ), + }, + }; + } + // Fallback shows the home page preview return { key: 'default', areas: { + sidebar: , preview: , - mobile: - canvas === 'edit' ? ( - - ) : undefined, + mobile: canvas === 'edit' && ( + + ), }, }; } diff --git a/packages/edit-site/src/components/sidebar-navigation-item/index.js b/packages/edit-site/src/components/sidebar-navigation-item/index.js index fad9f63421714..bbac07c42de0d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-item/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-item/index.js @@ -13,15 +13,42 @@ import { } from '@wordpress/components'; import { isRTL } from '@wordpress/i18n'; import { chevronRightSmall, chevronLeftSmall, Icon } from '@wordpress/icons'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; +import { useContext } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { unlock } from '../../lock-unlock'; +import { SidebarNavigationContext } from '../sidebar'; + +const { useHistory } = unlock( routerPrivateApis ); export default function SidebarNavigationItem( { className, icon, withChevron = false, suffix, + path, + onClick, children, ...props } ) { + const history = useHistory(); + const navigate = useContext( SidebarNavigationContext ); + + // If there is no custom click handler, create one that navigates to `path`. + function handleClick( e ) { + if ( onClick ) { + onClick( e ); + navigate( 'forward' ); + } else if ( path ) { + e.preventDefault(); + history.push( { path } ); + navigate( 'forward', `[id="${ path }"]` ); + } + } + return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js index 87ab8095ed827..f0585b410e40d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-global-styles/index.js @@ -5,10 +5,7 @@ import { __ } from '@wordpress/i18n'; import { edit, seen } from '@wordpress/icons'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; -import { - __experimentalNavigatorButton as NavigatorButton, - __experimentalVStack as VStack, -} from '@wordpress/components'; +import { __experimentalVStack as VStack } from '@wordpress/components'; import { useViewportMatch } from '@wordpress/compose'; import { BlockEditorProvider } from '@wordpress/block-editor'; import { useCallback } from '@wordpress/element'; @@ -48,13 +45,7 @@ export function SidebarNavigationItemGlobalStyles( props ) { [] ); if ( hasGlobalStyleVariations ) { - return ( - - ); + return ; } return ( { - if ( location?.path === '/' ) { - setEditorCanvasContainerView( undefined ); - } - }, [ setEditorCanvasContainerView, location?.path ] ); + setEditorCanvasContainerView( undefined ); + }, [ setEditorCanvasContainerView ] ); return ( - { __( 'Navigation' ) } - + { __( 'Styles' ) } - { __( 'Pages' ) } - - + { __( 'Templates' ) } - - + { __( 'Patterns' ) } - + } diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-item/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-item/index.js deleted file mode 100644 index 385938597da1f..0000000000000 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-item/index.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * WordPress dependencies - */ -import { __ } from '@wordpress/i18n'; -import { useDispatch } from '@wordpress/data'; -import { - __experimentalUseNavigator as useNavigator, - ExternalLink, -} from '@wordpress/components'; -import { useEntityRecord } from '@wordpress/core-data'; -import { decodeEntities } from '@wordpress/html-entities'; -import { pencil } from '@wordpress/icons'; - -/** - * Internal dependencies - */ -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import { unlock } from '../../lock-unlock'; -import { store as editSiteStore } from '../../store'; -import SidebarButton from '../sidebar-button'; - -export default function SidebarNavigationScreenNavigationItem() { - const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); - const { - params: { postType, postId }, - } = useNavigator(); - const { record } = useEntityRecord( 'postType', postType, postId ); - - return ( - setCanvasMode( 'edit' ) } - label={ __( 'Edit' ) } - icon={ pencil } - /> - } - description={ __( - 'Posts are entries listed in reverse chronological order on the site homepage or on the posts page.' - ) } - content={ - <> - { record?.link ? ( - - { record.link } - - ) : null } - { record - ? decodeEntities( record?.description?.rendered ) - : null } - - } - /> - ); -} diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js index 91f2cd0de9ff0..b795c686e77aa 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/index.js @@ -2,13 +2,11 @@ * WordPress dependencies */ import { useEntityRecord, store as coreStore } from '@wordpress/core-data'; -import { - __experimentalUseNavigator as useNavigator, - Spinner, -} from '@wordpress/components'; +import { Spinner } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; import { decodeEntities } from '@wordpress/html-entities'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -18,13 +16,16 @@ import ScreenNavigationMoreMenu from './more-menu'; import SingleNavigationMenu from './single-navigation-menu'; import useNavigationMenuHandlers from './use-navigation-menu-handlers'; import buildNavigationLabel from '../sidebar-navigation-screen-navigation-menus/build-navigation-label'; +import { unlock } from '../../lock-unlock'; + +const { useLocation } = unlock( routerPrivateApis ); export const postType = `wp_navigation`; export default function SidebarNavigationScreenNavigationMenu() { const { params: { postId }, - } = useNavigator(); + } = useLocation(); const { record: navigationMenu, isResolving } = useEntityRecord( 'postType', diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js index 67ade7b287e63..ce75f3155f33e 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menu/use-navigation-menu-handlers.js @@ -2,24 +2,25 @@ * WordPress dependencies */ import { store as coreStore } from '@wordpress/core-data'; -import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as noticesStore } from '@wordpress/notices'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies */ import { postType } from '.'; import { NAVIGATION_POST_TYPE } from '../../utils/constants'; +import { unlock } from '../../lock-unlock'; -function useDeleteNavigationMenu() { - const { goTo } = useNavigator(); +const { useHistory } = unlock( routerPrivateApis ); +function useDeleteNavigationMenu() { const { deleteEntityRecord } = useDispatch( coreStore ); - const { createSuccessNotice, createErrorNotice } = useDispatch( noticesStore ); + const history = useHistory(); const handleDelete = async ( navigationMenu ) => { const postId = navigationMenu?.id; @@ -41,7 +42,7 @@ function useDeleteNavigationMenu() { type: 'snackbar', } ); - goTo( '/navigation' ); + history.push( { path: '/navigation' } ); } catch ( error ) { createErrorNotice( sprintf( @@ -132,8 +133,7 @@ function useSaveNavigationMenu() { } function useDuplicateNavigationMenu() { - const { goTo } = useNavigator(); - + const history = useHistory(); const { saveEntityRecord } = useDispatch( coreStore ); const { createSuccessNotice, createErrorNotice } = @@ -165,7 +165,7 @@ function useDuplicateNavigationMenu() { createSuccessNotice( __( 'Duplicated Navigation Menu' ), { type: 'snackbar', } ); - goTo( `/navigation/${ postType }/${ savedRecord.id }` ); + history.push( { postType, postId: savedRecord.id } ); } } catch ( error ) { createErrorNotice( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js index 6b093ad27e25b..1e63225641895 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-navigation-menus/leaf-more-menu.js @@ -23,12 +23,11 @@ import { currentlyPreviewingTheme, } from '../../utils/is-previewing-theme'; import { unlock } from '../../lock-unlock'; -import { getPathFromURL } from '../sync-state-with-url/use-sync-path-with-url'; const { useLocation, useHistory } = unlock( routerPrivateApis ); export default function LeafMoreMenu( props ) { - const location = useLocation(); + const { params } = useLocation(); const history = useHistory(); const { block } = props; const { clientId } = block; @@ -74,7 +73,7 @@ export default function LeafMoreMenu( props ) { } ), }, { - backPath: getPathFromURL( location.params ), + backPath: params, } ); } @@ -88,12 +87,12 @@ export default function LeafMoreMenu( props ) { } ), }, { - backPath: getPathFromURL( location.params ), + backPath: params, } ); } }, - [ history ] + [ history, params ] ); return ( diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js index d6a43fd9b6a91..e8df6a2b7677d 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-page/index.js @@ -4,7 +4,6 @@ import { __ } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; import { - __experimentalUseNavigator as useNavigator, __experimentalVStack as VStack, ExternalLink, __experimentalTruncate as Truncate, @@ -29,7 +28,7 @@ import SidebarButton from '../sidebar-button'; import PageDetails from './page-details'; import SidebarNavigationScreenDetailsFooter from '../sidebar-navigation-screen-details-footer'; -const { useHistory } = unlock( routerPrivateApis ); +const { useLocation, useHistory } = unlock( routerPrivateApis ); const { PostActions } = unlock( editorPrivateApis ); export default function SidebarNavigationScreenPage( { backPath } ) { @@ -37,7 +36,7 @@ export default function SidebarNavigationScreenPage( { backPath } ) { const history = useHistory(); const { params: { postId }, - } = useNavigator(); + } = useLocation(); const { record, hasResolved } = useEntityRecord( 'postType', 'page', @@ -80,7 +79,7 @@ export default function SidebarNavigationScreenPage( { backPath } ) { canvas: 'view', } ); } - }, [ hasResolved, history ] ); + }, [ hasResolved, record, history ] ); const onActionPerformed = useCallback( ( actionId, items ) => { diff --git a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js index 693d16914869a..8607dad09241c 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen-pattern/index.js @@ -1,11 +1,11 @@ /** * WordPress dependencies */ -import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; import { useDispatch } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { pencil } from '@wordpress/icons'; import { getQueryArgs } from '@wordpress/url'; +import { privateApis as routerPrivateApis } from '@wordpress/router'; /** * Internal dependencies @@ -19,11 +19,14 @@ import { unlock } from '../../lock-unlock'; import TemplateActions from '../template-actions'; import { TEMPLATE_PART_POST_TYPE } from '../../utils/constants'; +const { useLocation, useHistory } = unlock( routerPrivateApis ); + export default function SidebarNavigationScreenPattern() { - const navigator = useNavigator(); + const history = useHistory(); + const location = useLocation(); const { params: { postType, postId }, - } = navigator; + } = location; const { categoryType } = getQueryArgs( window.location.href ); const { setCanvasMode } = unlock( useDispatch( editSiteStore ) ); @@ -36,8 +39,8 @@ export default function SidebarNavigationScreenPattern() { // page and the back button should return them to that list page. const backPath = ! categoryType && postType === TEMPLATE_PART_POST_TYPE - ? '/wp_template_part/all' - : '/patterns'; + ? { path: '/wp_template_part/all' } + : { path: '/patterns' }; return ( { - navigator.goTo( backPath ); + history.push( backPath ); } } /> { - navigator.goTo( '/' + postType ); + history.push( { path: '/' + postType } ); } } /> { const backPath = - backPathProp ?? location.state?.backPath; - if ( backPath ) { - navigator.goTo( backPath, { - isBack: true, - } ); - } else { - navigator.goToParent(); - } + backPathProp ?? + location.state?.backPath ?? + getBackPath( location.params ); + history.push( backPath ); + navigate( 'back' ); } } icon={ icon } label={ __( 'Back' ) } diff --git a/packages/edit-site/src/components/sidebar/index.js b/packages/edit-site/src/components/sidebar/index.js index 31a758218acfa..2cb7997b32bbe 100644 --- a/packages/edit-site/src/components/sidebar/index.js +++ b/packages/edit-site/src/components/sidebar/index.js @@ -1,117 +1,84 @@ -/** - * External dependencies - */ -import classNames from 'classnames'; - /** * WordPress dependencies */ -import { memo, useRef } from '@wordpress/element'; +import { __unstableMotion as motion } from '@wordpress/components'; +import { useReducedMotion } from '@wordpress/compose'; import { - __experimentalNavigatorProvider as NavigatorProvider, - __experimentalNavigatorScreen as NavigatorScreen, -} from '@wordpress/components'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; -import { useViewportMatch } from '@wordpress/compose'; -import { __ } from '@wordpress/i18n'; + useCallback, + createContext, + useState, + useRef, + useEffect, +} from '@wordpress/element'; +import { focus } from '@wordpress/dom'; -/** - * Internal dependencies - */ -import SidebarNavigationScreenMain from '../sidebar-navigation-screen-main'; -import SidebarNavigationScreenTemplate from '../sidebar-navigation-screen-template'; -import SidebarNavigationScreenPatterns from '../sidebar-navigation-screen-patterns'; -import SidebarNavigationScreenPattern from '../sidebar-navigation-screen-pattern'; -import useSyncPathWithURL, { - getPathFromURL, -} from '../sync-state-with-url/use-sync-path-with-url'; -import SidebarNavigationScreenNavigationMenus from '../sidebar-navigation-screen-navigation-menus'; -import SidebarNavigationScreenNavigationMenu from '../sidebar-navigation-screen-navigation-menu'; -import SidebarNavigationScreenGlobalStyles from '../sidebar-navigation-screen-global-styles'; -import SidebarNavigationScreenTemplatesBrowse from '../sidebar-navigation-screen-templates-browse'; -import SaveHub from '../save-hub'; -import { unlock } from '../../lock-unlock'; -import SidebarNavigationScreen from '../sidebar-navigation-screen'; -import DataViewsSidebarContent from '../sidebar-dataviews'; -import SidebarNavigationScreenPage from '../sidebar-navigation-screen-page'; - -const { useLocation } = unlock( routerPrivateApis ); +export const SidebarNavigationContext = createContext( () => {} ); -function SidebarScreenWrapper( { className, ...props } ) { - return ( - - ); +function getAnim( direction ) { + switch ( direction ) { + case 'back': + return { + initial: { opacity: 0, x: '-50px' }, + animate: { opacity: 1, x: '0' }, + }; + case 'forward': + return { + initial: { opacity: 0, x: '50px' }, + animate: { opacity: 1, x: '0' }, + }; + default: + return { initial: false, animate: false }; + } } -function SidebarScreens() { - useSyncPathWithURL(); - const isMobileViewport = useViewportMatch( 'medium', '<' ); +export default function SidebarContent( { routeKey, children } ) { + const [ navState, setNavState ] = useState( { + direction: null, + focusSelector: null, + } ); - return ( - <> - - - - - - - - - - - - - - } - /> - - - - - - - - { ! isMobileViewport && ( - - - - ) } - - - - - - - - - - - ); -} + const navigate = useCallback( ( direction, focusSelector = null ) => { + setNavState( ( prevState ) => ( { + direction, + focusSelector: + direction === 'forward' && focusSelector + ? focusSelector + : prevState.focusSelector, + } ) ); + }, [] ); + + const wrapperRef = useRef(); + useEffect( () => { + let elementToFocus; + if ( navState.direction === 'back' && navState.focusSelector ) { + elementToFocus = wrapperRef.current.querySelector( + navState.focusSelector + ); + } + if ( navState.direction !== null && ! elementToFocus ) { + const [ firstTabbable ] = focus.tabbable.find( wrapperRef.current ); + elementToFocus = firstTabbable ?? wrapperRef.current; + } + elementToFocus?.focus(); + }, [ navState ] ); -function Sidebar() { - const { params: urlParams } = useLocation(); - const initialPath = useRef( getPathFromURL( urlParams ) ); + const disableMotion = useReducedMotion(); + const { initial, animate } = getAnim( navState.direction ); return ( - <> - - - - - + +
+ + { children } + +
+
); } - -export default memo( Sidebar ); diff --git a/packages/edit-site/src/components/sidebar/style.scss b/packages/edit-site/src/components/sidebar/style.scss index 9bbe11f44ee7b..4be91c0cca19f 100644 --- a/packages/edit-site/src/components/sidebar/style.scss +++ b/packages/edit-site/src/components/sidebar/style.scss @@ -4,11 +4,13 @@ } .edit-site-sidebar__screen-wrapper { + overflow-x: auto; @include custom-scrollbars-on-hover(transparent, $gray-700); scrollbar-gutter: stable; display: flex; flex-direction: column; height: 100%; + max-height: 100%; // This matches the logo padding padding: 0 $grid-unit-15; diff --git a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js b/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js deleted file mode 100644 index 2aceee88e8acd..0000000000000 --- a/packages/edit-site/src/components/sync-state-with-url/use-sync-path-with-url.js +++ /dev/null @@ -1,147 +0,0 @@ -/** - * WordPress dependencies - */ -import { __experimentalUseNavigator as useNavigator } from '@wordpress/components'; -import { useEffect, useRef } from '@wordpress/element'; -import { privateApis as routerPrivateApis } from '@wordpress/router'; - -/** - * Internal dependencies - */ -import { unlock } from '../../lock-unlock'; -import { - TEMPLATE_POST_TYPE, - TEMPLATE_PART_POST_TYPE, - PATTERN_TYPES, -} from '../../utils/constants'; - -const { useLocation, useHistory } = unlock( routerPrivateApis ); - -export function getPathFromURL( urlParams ) { - let path = urlParams?.path ?? '/'; - - // Compute the navigator path based on the URL params. - if ( urlParams?.postType && urlParams?.postId ) { - switch ( urlParams.postType ) { - case PATTERN_TYPES.user: - case TEMPLATE_POST_TYPE: - case TEMPLATE_PART_POST_TYPE: - case 'page': - path = `/${ encodeURIComponent( - urlParams.postType - ) }/${ encodeURIComponent( urlParams.postId ) }`; - break; - default: - path = `/navigation/${ encodeURIComponent( - urlParams.postType - ) }/${ encodeURIComponent( urlParams.postId ) }`; - } - } - - return path; -} - -function isSubset( subset, superset ) { - return Object.entries( subset ).every( ( [ key, value ] ) => { - return superset[ key ] === value; - } ); -} - -export default function useSyncPathWithURL() { - const history = useHistory(); - const { params: urlParams } = useLocation(); - const { - location: navigatorLocation, - params: navigatorParams, - goTo, - } = useNavigator(); - const isMounting = useRef( true ); - - useEffect( - () => { - // The navigatorParams are only initially filled properly when the - // navigator screens mount. so we ignore the first synchronisation. - if ( isMounting.current ) { - isMounting.current = false; - return; - } - - function updateUrlParams( newUrlParams ) { - if ( isSubset( newUrlParams, urlParams ) ) { - return; - } - const updatedParams = { - ...urlParams, - ...newUrlParams, - }; - history.push( updatedParams ); - } - - if ( navigatorParams?.postType && navigatorParams?.postId ) { - updateUrlParams( { - postType: navigatorParams?.postType, - postId: navigatorParams?.postId, - path: undefined, - layout: undefined, - } ); - } else if ( - navigatorLocation.path.startsWith( '/page/' ) && - navigatorParams?.postId - ) { - updateUrlParams( { - postType: 'page', - postId: navigatorParams?.postId, - path: undefined, - layout: undefined, - } ); - } else if ( navigatorLocation.path === '/patterns' ) { - updateUrlParams( { - postType: undefined, - postId: undefined, - canvas: undefined, - path: navigatorLocation.path, - } ); - } else if ( - // These sidebar paths are special in the sense that the url in these pages may or may not have a postId and we need to retain it if it has. - // The "type" property should be kept as well. - navigatorLocation.path === '/page' || - navigatorLocation.path === '/wp_template' || - navigatorLocation.path === '/wp_template_part/all' - ) { - updateUrlParams( { - postType: undefined, - categoryType: undefined, - categoryId: undefined, - path: navigatorLocation.path, - } ); - } else { - updateUrlParams( { - postType: undefined, - postId: undefined, - categoryType: undefined, - categoryId: undefined, - layout: undefined, - path: - navigatorLocation.path === '/' - ? undefined - : navigatorLocation.path, - } ); - } - }, - // Trigger only when navigator changes to prevent infinite loops. - // eslint-disable-next-line react-hooks/exhaustive-deps - [ navigatorLocation?.path, navigatorParams ] - ); - - useEffect( - () => { - const path = getPathFromURL( urlParams ); - if ( navigatorLocation.path !== path ) { - goTo( path ); - } - }, - // Trigger only when URL changes to prevent infinite loops. - // eslint-disable-next-line react-hooks/exhaustive-deps - [ urlParams ] - ); -}