feat(ui): View Transitions crossfade for library switches
Where the browser supports it (Chrome 111+, Safari 18+, Firefox 139+), switchWithTransition now uses the native View Transitions API: the old shelves are snapshotted, the fetch + swap happen behind the dim, and the two snapshots crossfade — no blank phase, no manual opacity choreography. The dim + spinner is hidden inside the update so it blends away as part of the transition. Browsers without the API keep the existing dim + fade sequence unchanged. Zero dependencies — the crossfade is the browser's own.
This commit is contained in:
1 parent
a11b4a9cc4
commit
a31da89df5
1 file changed
+27
@@ -15,6 +15,33 @@ export async function switchWithTransition(
|
|||||||
|
|
||||||
if (!container || !loading) return;
|
if (!container || !loading) return;
|
||||||
|
|
||||||
|
// View Transitions (native, where supported): the browser snapshots the
|
||||||
|
// old shelves, fetchFn swaps the DOM, and the two snapshots crossfade —
|
||||||
|
// no blank phase, no manual opacity choreography. The dim + spinner is
|
||||||
|
// shown before the snapshot and hidden inside the update, so the dim
|
||||||
|
// blends away as part of the crossfade. Browsers without the API fall
|
||||||
|
// through to the dim + fade sequence below.
|
||||||
|
const doc = document as Document & {
|
||||||
|
startViewTransition?: (updateCallback: () => void | Promise<void>) => {
|
||||||
|
finished: Promise<void>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
if (doc.startViewTransition) {
|
||||||
|
try {
|
||||||
|
loading.classList.remove("hidden");
|
||||||
|
const transition = doc.startViewTransition(async () => {
|
||||||
|
await fetchFn();
|
||||||
|
loading.classList.add("hidden");
|
||||||
|
});
|
||||||
|
await transition.finished;
|
||||||
|
} catch (error) {
|
||||||
|
loading.classList.add("hidden");
|
||||||
|
showToast("Failed to load library", "error");
|
||||||
|
console.error("Switch library error:", error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
container.classList.add(
|
container.classList.add(
|
||||||
"opacity-0",
|
"opacity-0",
|
||||||
|
|||||||
Reference in new issue
Block a user