From c4aba2c74f9a1cedadcbe1d8a76870f81416c649 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 7 Nov 2025 22:44:07 +0100 Subject: [PATCH 1/3] Add direction aware view transitions --- .../src/routes/posts.route.tsx | 28 +++++++++++++-- .../react/view-transitions/src/styles.css | 36 +++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/examples/react/view-transitions/src/routes/posts.route.tsx b/examples/react/view-transitions/src/routes/posts.route.tsx index 88296c3c54a..9c091acf966 100644 --- a/examples/react/view-transitions/src/routes/posts.route.tsx +++ b/examples/react/view-transitions/src/routes/posts.route.tsx @@ -1,4 +1,4 @@ -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute, useRouter } from '@tanstack/react-router' import * as React from 'react' import { Link, Outlet } from '@tanstack/react-router' import { fetchPosts } from '../posts' @@ -10,6 +10,7 @@ export const Route = createFileRoute('/posts')({ function PostsLayoutComponent() { const posts = Route.useLoaderData() + const router = useRouter() return (
@@ -25,8 +26,29 @@ function PostsLayoutComponent() { }} className="block py-1 text-blue-600 hover:opacity-75" activeProps={{ className: 'font-bold underline' }} - // see styles.css for 'warp' transition - viewTransition={{ types: ['warp'] }} + viewTransition={{ + types: ({ fromLocation, toLocation }) => { + const fromRoute = router + .matchRoutes(fromLocation?.pathname ?? '/') + .find((entry) => entry.routeId === '/posts/$postId') + const toRoute = router + .matchRoutes(toLocation?.pathname ?? '/') + .find((entry) => entry.routeId === '/posts/$postId') + + const fromIndex = Number(fromRoute?.params.postId) + const toIndex = Number(toRoute?.params.postId) + + if ( + Number.isNaN(fromIndex) || + Number.isNaN(toIndex) || + fromIndex === toIndex + ) { + return false // no transition + } + + return fromIndex > toIndex ? ['warp-backwards'] : ['warp'] + }, + }} >
{post.title.substring(0, 20)}
diff --git a/examples/react/view-transitions/src/styles.css b/examples/react/view-transitions/src/styles.css index 818667133d4..172cf34be99 100644 --- a/examples/react/view-transitions/src/styles.css +++ b/examples/react/view-transitions/src/styles.css @@ -87,6 +87,16 @@ html:active-view-transition-type(warp) { } } +html:active-view-transition-type(warp-backwards) { + &::view-transition-old(post) { + animation: 400ms ease-out both warp-out-backwards; + } + + &::view-transition-new(post) { + animation: 400ms ease-out both warp-in-backwards; + } +} + @keyframes warp-out { from { opacity: 1; @@ -112,3 +122,29 @@ html:active-view-transition-type(warp) { transform: scale(1) rotate(0deg); } } + +@keyframes warp-in-backwards { + from { + opacity: 0; + filter: blur(15px) brightness(1.8); + transform: scale(0.9) rotate(45deg); + } + to { + opacity: 1; + filter: blur(0) brightness(1); + transform: scale(1) rotate(0deg); + } +} + +@keyframes warp-out-backwards { + from { + opacity: 1; + filter: blur(0) brightness(1); + transform: scale(1) rotate(0deg); + } + to { + opacity: 0; + filter: blur(15px) brightness(1.8); + transform: scale(1.1) rotate(-90deg); + } +} From a45c8b7636985e3007e493caee4aec04df9dadce Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 7 Nov 2025 22:47:37 +0100 Subject: [PATCH 2/3] Restore comment --- examples/react/view-transitions/src/routes/posts.route.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/react/view-transitions/src/routes/posts.route.tsx b/examples/react/view-transitions/src/routes/posts.route.tsx index 9c091acf966..e3740808f5e 100644 --- a/examples/react/view-transitions/src/routes/posts.route.tsx +++ b/examples/react/view-transitions/src/routes/posts.route.tsx @@ -26,6 +26,7 @@ function PostsLayoutComponent() { }} className="block py-1 text-blue-600 hover:opacity-75" activeProps={{ className: 'font-bold underline' }} + // see styles.css for 'warp' and 'warp-backwards' transition viewTransition={{ types: ({ fromLocation, toLocation }) => { const fromRoute = router From 9a0726a8cd4d5c3c3a43ce82af4b30b0c1a6d5f2 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 7 Nov 2025 23:05:07 +0100 Subject: [PATCH 3/3] Linter fix --- .../react/view-transitions/src/routes/posts.route.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/react/view-transitions/src/routes/posts.route.tsx b/examples/react/view-transitions/src/routes/posts.route.tsx index e3740808f5e..983d2943907 100644 --- a/examples/react/view-transitions/src/routes/posts.route.tsx +++ b/examples/react/view-transitions/src/routes/posts.route.tsx @@ -1,6 +1,10 @@ -import { createFileRoute, useRouter } from '@tanstack/react-router' +import { + Link, + Outlet, + createFileRoute, + useRouter, +} from '@tanstack/react-router' import * as React from 'react' -import { Link, Outlet } from '@tanstack/react-router' import { fetchPosts } from '../posts' export const Route = createFileRoute('/posts')({