first publish
This commit is contained in:
commit
b8e41b4d55
147 files changed
+19367
No files matched your search
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user