32 lines
1.4 KiB
TypeScript
32 lines
1.4 KiB
TypeScript
// SvelteKit `onNavigate` helper — wraps client-side navigation in the
|
|
// browser's View Transitions API so route changes cross-fade cleanly and
|
|
// shared-element transitions (Fleet card → Server detail hero) morph.
|
|
//
|
|
// 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.
|
|
type NavigationLike = { complete: Promise<unknown> };
|
|
|
|
export function enableViewTransitions(navigation: NavigationLike): Promise<void> | 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>) => { ready: Promise<void>; finished: Promise<void> };
|
|
}).startViewTransition;
|
|
|
|
if (typeof start !== 'function') return;
|
|
|
|
return new Promise<void>((resolve) => {
|
|
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(); }
|
|
});
|
|
}
|