From 8a87982d4b88be5824e61a2fa32d588289bbc806 Mon Sep 17 00:00:00 2001 From: Philipp Melab Date: Mon, 3 Feb 2025 09:47:19 +0100 Subject: [PATCH] feat: make client router support view transitions --- packages/waku/src/router/client.ts | 67 ++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/packages/waku/src/router/client.ts b/packages/waku/src/router/client.ts index 09a272408..61b9f939d 100644 --- a/packages/waku/src/router/client.ts +++ b/packages/waku/src/router/client.ts @@ -349,17 +349,25 @@ const InnerRouter = ({ const changeRoute: ChangeRoute = useCallback( (route, options) => { const { skipRefetch } = options || {}; - startTransition(() => { - if (!staticPathSet.has(route.path) && !skipRefetch) { - const rscPath = encodeRoutePath(route.path); - const rscParams = createRscParams(route.query); - refetch(rscPath, rscParams); - } - if (options.shouldScroll) { - handleScroll(); - } - setRoute(route); - }); + const performChange = () => { + startTransition(() => { + if (!staticPathSet.has(route.path) && !skipRefetch) { + const rscPath = encodeRoutePath(route.path); + const rscParams = createRscParams(route.query); + refetch(rscPath, rscParams); + } + if (options.shouldScroll) { + handleScroll(); + } + setRoute(route); + }); + }; + + if ('startViewTransition' in document && !skipRefetch) { + document.startViewTransition(performChange); + } else { + performChange(); + } }, [refetch, staticPathSet], ); @@ -380,7 +388,13 @@ const InnerRouter = ({ useEffect(() => { const callback = () => { const route = parseRoute(new URL(window.location.href)); - changeRoute(route, { shouldScroll: true }); + if ('startViewTransition' in document) { + (document as any).startViewTransition(() => { + changeRoute(route, { shouldScroll: true }); + }); + } else { + changeRoute(route, { shouldScroll: true }); + } }; window.addEventListener('popstate', callback); return () => { @@ -395,16 +409,27 @@ const InnerRouter = ({ url.search = query; url.hash = ''; if (path !== '/404') { - window.history.pushState( - { - ...window.history.state, - waku_new_path: url.pathname !== window.location.pathname, - }, - '', - url, - ); + const performNavigation = () => { + window.history.pushState( + { + ...window.history.state, + waku_new_path: url.pathname !== window.location.pathname, + }, + '', + url, + ); + changeRoute(parseRoute(url), { + skipRefetch: true, + shouldScroll: false, + }); + }; + + if ('startViewTransition' in document) { + (document as any).startViewTransition(performNavigation); + } else { + performNavigation(); + } } - changeRoute(parseRoute(url), { skipRefetch: true, shouldScroll: false }); }; locationListeners.add(callback); return () => {