diff --git a/examples/react/view-transitions/src/main.tsx b/examples/react/view-transitions/src/main.tsx index 0275c31e397..065d69a2cf8 100644 --- a/examples/react/view-transitions/src/main.tsx +++ b/examples/react/view-transitions/src/main.tsx @@ -12,9 +12,32 @@ const router = createRouter({ scrollRestoration: true, /* Using defaultViewTransition would prevent the need to - manually add `viewTransition: true` to every navigation + manually add `viewTransition: true` to every navigation. + + If defaultViewTransition.types is a function, it will be called with the + location change info and should return an array of view transition types. + This is useful if you want to have different view transitions depending on + the navigation's specifics. + + An example use case is sliding in a direction based on the index of the + previous and next routes when navigating via browser history back and forth. */ // defaultViewTransition: true + // OR + // defaultViewTransition: { + // types: ({ fromLocation, toLocation }) => { + // let direction = 'none' + + // if (fromLocation) { + // const fromIndex = fromLocation.state.__TSR_index + // const toIndex = toLocation.state.__TSR_index + + // direction = fromIndex > toIndex ? 'right' : 'left' + // } + + // return [`slide-${direction}`] + // }, + // }, }) // Register things for typesafety diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index e458e3e9311..cdc2c1201d9 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -670,7 +670,15 @@ export type AnyRouterWithContext = RouterCore< export type AnyRouter = RouterCore export interface ViewTransitionOptions { - types: Array + types: + | Array + | ((locationChangeInfo: { + fromLocation?: ParsedLocation + toLocation: ParsedLocation + pathChanged: boolean + hrefChanged: boolean + hashChanged: boolean + }) => Array) } export function defaultSerializeError(err: unknown) { @@ -2172,9 +2180,22 @@ export class RouterCore< typeof shouldViewTransition === 'object' && this.isViewTransitionTypesSupported ) { + const next = this.latestLocation + const prevLocation = this.state.resolvedLocation + + const resolvedViewTransitionTypes = + typeof shouldViewTransition.types === 'function' + ? shouldViewTransition.types( + getLocationChangeInfo({ + resolvedLocation: prevLocation, + location: next, + }), + ) + : shouldViewTransition.types + startViewTransitionParams = { update: fn, - types: shouldViewTransition.types, + types: resolvedViewTransitionTypes, } } else { startViewTransitionParams = fn