diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx index c20e7aaa5c533..a801f1245ab84 100644 --- a/packages/components/src/navigator/navigator-provider/component.tsx +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -42,35 +42,17 @@ function NavigatorProvider( >( [ { path: initialPath, - isBack: false, - isInitial: true, }, ] ); const push: NavigatorContextType[ 'push' ] = useCallback( ( path, options = {} ) => { - const { focusTargetSelector, ...restOptions } = options; - - // Notes: - // - the `isBack` flag is set to `false` when navigating forwards on both - // the previous and the new location. - // - the `isInitial` flag is set to `false` for the new location, to make - // sure it doesn't get overridden by mistake. - // - the `focusTargetSelector` prop is set on the current (soon previous) - // location, as it is used to restore focus in NavigatorScreen. The - // remaining options are instead set on the new location being pushed. setLocationHistory( [ - ...locationHistory.slice( 0, -1 ), - { - ...locationHistory[ locationHistory.length - 1 ], - isBack: false, - focusTargetSelector, - }, + ...locationHistory, { - ...restOptions, + ...options, path, isBack: false, - isInitial: false, }, ] ); }, @@ -79,7 +61,6 @@ function NavigatorProvider( const pop: NavigatorContextType[ 'pop' ] = useCallback( () => { if ( locationHistory.length > 1 ) { - // Force the `isBack` flag to `true` when navigating back. setLocationHistory( [ ...locationHistory.slice( 0, -2 ), { @@ -92,7 +73,10 @@ function NavigatorProvider( const navigatorContextValue: NavigatorContextType = useMemo( () => ( { - location: locationHistory[ locationHistory.length - 1 ], + location: { + ...locationHistory[ locationHistory.length - 1 ], + isInitial: locationHistory.length === 1, + }, push, pop, } ), diff --git a/packages/components/src/navigator/navigator-screen/component.tsx b/packages/components/src/navigator/navigator-screen/component.tsx index 9cf5812417718..7cf629a7b0f6d 100644 --- a/packages/components/src/navigator/navigator-screen/component.tsx +++ b/packages/components/src/navigator/navigator-screen/component.tsx @@ -11,7 +11,11 @@ import { css } from '@emotion/react'; */ import { focus } from '@wordpress/dom'; import { useContext, useEffect, useMemo, useRef } from '@wordpress/element'; -import { useReducedMotion, useMergeRefs } from '@wordpress/compose'; +import { + useReducedMotion, + useMergeRefs, + usePrevious, +} from '@wordpress/compose'; import { isRTL } from '@wordpress/i18n'; /** @@ -50,6 +54,8 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) { const isMatch = location.path === path; const wrapperRef = useRef< HTMLDivElement >( null ); + const previousLocation = usePrevious( location ); + const cx = useCx(); const classes = useMemo( () => @@ -80,9 +86,9 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) { // When navigating back, if a selector is provided, use it to look for the // target element (assumed to be a node inside the current NavigatorScreen) - if ( location.isBack && location.focusTargetSelector ) { + if ( location.isBack && previousLocation?.focusTargetSelector ) { elementToFocus = wrapperRef.current.querySelector( - location.focusTargetSelector + previousLocation.focusTargetSelector ); }