From e83e1afc0a55a4531ee3012bf824611626a35e01 Mon Sep 17 00:00:00 2001 From: Robert Anderson Date: Thu, 13 Jul 2023 11:46:58 +1000 Subject: [PATCH] Site Editor: Make sidebar back button go back instead of up if possible --- .../sidebar-navigation-screen/index.js | 19 ++- .../use-sync-path-with-url.js | 139 +++++++++--------- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/packages/edit-site/src/components/sidebar-navigation-screen/index.js b/packages/edit-site/src/components/sidebar-navigation-screen/index.js index 919e7e92d721d5..32367c32b71e9c 100644 --- a/packages/edit-site/src/components/sidebar-navigation-screen/index.js +++ b/packages/edit-site/src/components/sidebar-navigation-screen/index.js @@ -4,7 +4,6 @@ import { __experimentalHStack as HStack, __experimentalHeading as Heading, - __experimentalNavigatorToParentButton as NavigatorToParentButton, __experimentalUseNavigator as useNavigator, __experimentalVStack as VStack, } from '@wordpress/components'; @@ -41,7 +40,7 @@ export default function SidebarNavigationScreen( { }; }, [] ); const { getTheme } = useSelect( coreStore ); - const { goTo } = useNavigator(); + const navigator = useNavigator(); const theme = getTheme( currentlyPreviewingTheme() ); const icon = isRTL() ? chevronRight : chevronLeft; @@ -58,16 +57,24 @@ export default function SidebarNavigationScreen( { className="edit-site-sidebar-navigation-screen__title-icon" > { ! isRoot && ! backPath && ( - { + if ( navigator.location.isInitial ) { + navigator.goToParent( { replace: true } ); + } else { + navigator.goBack(); + } + } } + icon={ icon } label={ __( 'Back' ) } showTooltip={ false } /> ) } { ! isRoot && backPath && ( goTo( backPath, { isBack: true } ) } + onClick={ () => + navigator.goTo( backPath, { isBack: true } ) + } icon={ icon } label={ __( 'Back' ) } showTooltip={ false } 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 index 45f7eb1b044c1f..86928c1920a948 100644 --- 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 @@ -36,6 +36,12 @@ export function getPathFromURL( urlParams ) { 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(); @@ -44,76 +50,77 @@ export default function useSyncPathWithURL() { params: navigatorParams, goTo, } = useNavigator(); - const currentUrlParams = useRef( urlParams ); - const currentPath = useRef( navigatorLocation.path ); 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 ( - Object.entries( newUrlParams ).every( ( [ key, value ] ) => { - return currentUrlParams.current[ key ] === value; - } ) - ) { + 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; } - const updatedParams = { - ...currentUrlParams.current, - ...newUrlParams, - }; - currentUrlParams.current = updatedParams; - history.push( updatedParams ); - } - if ( navigatorParams?.postType && navigatorParams?.postId ) { - updateUrlParams( { - postType: navigatorParams?.postType, - postId: navigatorParams?.postId, - path: undefined, - } ); - } else if ( - navigatorLocation.path.startsWith( '/page/' ) && - navigatorParams?.postId - ) { - updateUrlParams( { - postType: 'page', - postId: navigatorParams?.postId, - path: undefined, - } ); - } else if ( navigatorLocation.path === '/patterns' ) { - updateUrlParams( { - postType: undefined, - postId: undefined, - canvas: undefined, - path: navigatorLocation.path, - } ); - } else { - updateUrlParams( { - postType: undefined, - postId: undefined, - categoryType: undefined, - categoryId: undefined, - path: - navigatorLocation.path === '/' - ? undefined - : navigatorLocation.path, - } ); - } - }, [ navigatorLocation?.path, navigatorParams, history ] ); + function updateUrlParams( newUrlParams ) { + if ( isSubset( newUrlParams, urlParams ) ) { + return; + } + const updatedParams = { + ...urlParams, + ...newUrlParams, + }; + history.push( updatedParams ); + } - useEffect( () => { - currentUrlParams.current = urlParams; - const path = getPathFromURL( urlParams ); - if ( currentPath.current !== path ) { - currentPath.current = path; - goTo( path ); - } - }, [ urlParams, goTo ] ); + if ( navigatorParams?.postType && navigatorParams?.postId ) { + updateUrlParams( { + postType: navigatorParams?.postType, + postId: navigatorParams?.postId, + path: undefined, + } ); + } else if ( + navigatorLocation.path.startsWith( '/page/' ) && + navigatorParams?.postId + ) { + updateUrlParams( { + postType: 'page', + postId: navigatorParams?.postId, + path: undefined, + } ); + } else if ( navigatorLocation.path === '/patterns' ) { + updateUrlParams( { + postType: undefined, + postId: undefined, + canvas: undefined, + path: navigatorLocation.path, + } ); + } else { + updateUrlParams( { + postType: undefined, + postId: undefined, + categoryType: undefined, + categoryId: 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 ] + ); }