From 1268f86f746e479d0144f959df209476b7555904 Mon Sep 17 00:00:00 2001 From: Burak Can Date: Tue, 22 Apr 2025 22:47:56 +0000 Subject: [PATCH 1/2] feat(react-router): accept function as ViewTransitionOptions['types'] --- examples/react/view-transitions/src/main.tsx | 25 ++++++++++++++++++- packages/router-core/src/router.ts | 26 ++++++++++++++++++-- 2 files changed, 48 insertions(+), 3 deletions(-) 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..51c592b9779 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,23 @@ export class RouterCore< typeof shouldViewTransition === 'object' && this.isViewTransitionTypesSupported ) { + const next = this.latestLocation + const prevLocation = this.state.resolvedLocation + + let types = shouldViewTransition.types + + if (typeof types === 'function') { + types = types( + getLocationChangeInfo({ + resolvedLocation: prevLocation, + location: next, + }), + ) + } + startViewTransitionParams = { update: fn, - types: shouldViewTransition.types, + types, } } else { startViewTransitionParams = fn From 419373a08a7470b9cd66eb797425bb616c0f16d0 Mon Sep 17 00:00:00 2001 From: SeanCassiere <33615041+SeanCassiere@users.noreply.github.com> Date: Wed, 23 Apr 2025 13:25:08 +1200 Subject: [PATCH 2/2] apply code-review suggestion from @SeanCassiere --- packages/router-core/src/router.ts | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index 51c592b9779..cdc2c1201d9 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -2183,20 +2183,19 @@ export class RouterCore< const next = this.latestLocation const prevLocation = this.state.resolvedLocation - let types = shouldViewTransition.types - - if (typeof types === 'function') { - types = types( - getLocationChangeInfo({ - resolvedLocation: prevLocation, - location: next, - }), - ) - } + const resolvedViewTransitionTypes = + typeof shouldViewTransition.types === 'function' + ? shouldViewTransition.types( + getLocationChangeInfo({ + resolvedLocation: prevLocation, + location: next, + }), + ) + : shouldViewTransition.types startViewTransitionParams = { update: fn, - types, + types: resolvedViewTransitionTypes, } } else { startViewTransitionParams = fn