Handle interrupted navigation transitions

This commit is contained in:
2026-10-05 19:25:41 -04:00
parent 2670f3b701
commit f20cfe1300
2 changed files with 34 additions and 7 deletions
+11 -7
View File
@@ -2,8 +2,7 @@
// browser's View Transitions API so route changes cross-fade cleanly and
// shared-element transitions (Fleet card → Server detail hero) morph.
//
// Chromium ships the API today; Firefox and Safari fall through to a plain
// navigation — same behavior as before, just without the transition.
// Browsers without the API use ordinary navigation.
// Structural type — accepts whatever SvelteKit passes to onNavigate without
// coupling to a specific @sveltejs/kit version's type name.
@@ -13,15 +12,20 @@ export function enableViewTransitions(navigation: NavigationLike): Promise<void>
// Feature-detect without a custom Document extension — the DOM lib type
// varies between TS versions, and any narrowing has to survive both.
const start = (document as unknown as {
startViewTransition?: (cb: () => void | Promise<void>) => unknown;
startViewTransition?: (cb: () => void | Promise<void>) => { ready: Promise<void>; finished: Promise<void> };
}).startViewTransition;
if (typeof start !== 'function') return;
return new Promise<void>((resolve) => {
start.call(document, async () => {
resolve();
await navigation.complete;
});
try {
const transition = start.call(document, async () => {
resolve();
// Another navigation can supersede this one during its animation.
await navigation.complete.catch(() => {});
});
void transition.ready.catch(() => {});
void transition.finished.catch(() => {}).finally(resolve);
} catch { resolve(); }
});
}