Files
Anelia-Wolf/src/components/motion/transition-store.ts
T
2026-09-06 17:21:52 +02:00

56 lines
1.4 KiB
TypeScript

/**
* Tiny framework-free store for the page transition („Umblättern“).
* TransitionLink calls `startTransition`; Curtain subscribes, animates,
* pushes the route and finally calls `endTransition`.
*/
export type TransitionPhase = "idle" | "cover" | "pushed" | "reveal";
export interface TransitionState {
phase: TransitionPhase;
href: string | null;
label?: string;
}
type Listener = (state: TransitionState) => void;
let state: TransitionState = { phase: "idle", href: null };
const listeners = new Set<Listener>();
function emit() {
listeners.forEach((cb) => cb(state));
}
/** Begins a transition. Returns false when one is already running (double clicks). */
export function startTransition(href: string, label?: string): boolean {
if (state.phase !== "idle") return false;
state = { phase: "cover", href, label };
emit();
return true;
}
/** Internal: Curtain advances the phase. */
export function setTransitionPhase(phase: TransitionPhase) {
state = { ...state, phase };
emit();
}
export function endTransition() {
state = { phase: "idle", href: null };
emit();
}
export function isTransitioning(): boolean {
return state.phase !== "idle";
}
export function getTransitionState(): TransitionState {
return state;
}
export function subscribe(cb: Listener): () => void {
listeners.add(cb);
return () => {
listeners.delete(cb);
};
}