From d700ffea9fb686bf1a2a5438e16225fdeab3dc54 Mon Sep 17 00:00:00 2001 From: Marco Ciampini Date: Fri, 3 Dec 2021 12:19:17 +0100 Subject: [PATCH 01/17] `Navigator`: add basic history support --- packages/components/src/navigator/context.ts | 6 ++- .../navigator-provider/component.tsx | 44 ++++++++++++++++--- .../navigator/navigator-screen/component.tsx | 10 ++--- .../components/src/navigator/stories/index.js | 10 ++--- packages/components/src/navigator/types.ts | 21 ++++----- .../components/src/navigator/use-navigator.ts | 8 ++-- 6 files changed, 68 insertions(+), 31 deletions(-) diff --git a/packages/components/src/navigator/context.ts b/packages/components/src/navigator/context.ts index 17b26fb9c14ad5..cf326f7bc352b9 100644 --- a/packages/components/src/navigator/context.ts +++ b/packages/components/src/navigator/context.ts @@ -8,5 +8,9 @@ import { createContext } from '@wordpress/element'; */ import type { NavigatorContext as NavigatorContextType } from './types'; -const initialContextValue: NavigatorContextType = [ {}, () => {} ]; +const initialContextValue: NavigatorContextType = { + location: {}, + push: () => {}, + pop: () => {}, +}; export const NavigatorContext = createContext( initialContextValue ); diff --git a/packages/components/src/navigator/navigator-provider/component.tsx b/packages/components/src/navigator/navigator-provider/component.tsx index df17ba55b05591..9f35ad954ce784 100644 --- a/packages/components/src/navigator/navigator-provider/component.tsx +++ b/packages/components/src/navigator/navigator-provider/component.tsx @@ -21,7 +21,11 @@ import { import { useCx } from '../../utils/hooks/use-cx'; import { View } from '../../view'; import { NavigatorContext } from '../context'; -import type { NavigatorProviderProps, NavigatorPath } from '../types'; +import type { + NavigatorProviderProps, + NavigatorLocation, + NavigatorContext as NavigatorContextType, +} from '../types'; function NavigatorProvider( props: WordPressComponentProps< NavigatorProviderProps, 'div' >, @@ -34,9 +38,39 @@ function NavigatorProvider( ...otherProps } = useContextSystem( props, 'NavigatorProvider' ); - const [ path, setPath ] = useState< NavigatorPath >( { - path: initialPath, - } ); + const [ locationHistory, setLocationHistory ] = useState< + NavigatorLocation[] + >( [ + { + path: initialPath, + }, + ] ); + + const navigatorContextValue: NavigatorContextType = { + location: locationHistory[ locationHistory.length - 1 ], + push: ( path, options ) => { + setLocationHistory( [ + ...locationHistory, + { + path, + isBack: false, + navigationTriggerElement: options?.navigationTriggerElement, + }, + ] ); + }, + pop: () => { + if ( locationHistory.length > 1 ) { + setLocationHistory( [ + ...locationHistory.slice( 0, -2 ), + // Force the `isBack` flag to `true` when navigating back. + { + ...locationHistory[ locationHistory.length - 2 ], + isBack: true, + }, + ] ); + } + }, + }; const cx = useCx(); const classes = useMemo( @@ -47,7 +81,7 @@ function NavigatorProvider( return ( - + { children } diff --git a/packages/components/src/navigator/navigator-screen/component.tsx b/packages/components/src/navigator/navigator-screen/component.tsx index 85631b0b5227a5..9590cf5711e652 100644 --- a/packages/components/src/navigator/navigator-screen/component.tsx +++ b/packages/components/src/navigator/navigator-screen/component.tsx @@ -46,8 +46,8 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) { ); const prefersReducedMotion = useReducedMotion(); - const [ currentPath ] = useContext( NavigatorContext ); - const isMatch = currentPath.path === path; + const { location } = useContext( NavigatorContext ); + const isMatch = location.path === path; const ref = useFocusOnMount(); const cx = useCx(); @@ -96,8 +96,7 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) { const initial = { opacity: 0, x: - ( isRTL() && currentPath.isBack ) || - ( ! isRTL() && ! currentPath.isBack ) + ( isRTL() && location.isBack ) || ( ! isRTL() && ! location.isBack ) ? 50 : -50, }; @@ -105,8 +104,7 @@ function NavigatorScreen( props: Props, forwardedRef: Ref< any > ) { delay: animationExitDelay, opacity: 0, x: - ( ! isRTL() && currentPath.isBack ) || - ( isRTL() && ! currentPath.isBack ) + ( ! isRTL() && location.isBack ) || ( isRTL() && ! location.isBack ) ? 50 : -50, transition: { diff --git a/packages/components/src/navigator/stories/index.js b/packages/components/src/navigator/stories/index.js index 97e527216eef38..6e04436804f303 100644 --- a/packages/components/src/navigator/stories/index.js +++ b/packages/components/src/navigator/stories/index.js @@ -20,12 +20,12 @@ export default { function NavigatorButton( { path, isBack = false, ...props } ) { const navigator = useNavigator(); + + const handleOnClick = () => + isBack ? navigator.pop() : navigator.push( path ); + return ( -