UNPKG

@omicrxn/mercury

Version:

Mercury is a Svelte animation library powered by Motion. It simplifies complex animations with Svelte actions, provides layout and exit animations, and integrates seamlessly with Svelte features.

51 lines (50 loc) 1.84 kB
const scopes = new WeakMap(); const MERCURY_CONTROLS = Symbol('mercury:controls'); /** Parent element used to coordinate enter/exit timing within a slot. */ export const getPresenceScope = (element) => element.parentElement ?? document.documentElement; const getScopeState = (scope) => { const state = scopes.get(scope) ?? { count: 0, listeners: new Set() }; scopes.set(scope, state); return state; }; /** Whether a wait-mode exit is still running in this scope. */ export const hasPendingWaitExit = (element) => (scopes.get(getPresenceScope(element))?.count ?? 0) > 0; /** Register a wait-mode exit so subsequent enters in the same scope defer. */ export const registerWaitExit = (element) => { getScopeState(getPresenceScope(element)).count += 1; }; /** Call when a wait-mode exit animation finishes or is cancelled. */ export const completeWaitExit = (element) => { const scope = getPresenceScope(element); const state = scopes.get(scope); if (!state) return; state.count -= 1; if (state.count > 0) return; const listeners = [...state.listeners]; scopes.delete(scope); for (const listener of listeners) listener(); }; /** * Run `fn` once any active wait-mode exit in this scope has finished. * Waits one macrotask so out:presence can register in the same commit. */ export const runAfterPendingExit = (element, fn) => { setTimeout(() => { if (!hasPendingWaitExit(element)) { fn(); return; } getScopeState(getPresenceScope(element)).listeners.add(fn); }, 0); }; export const registerMercuryControls = (element, controls) => { element[MERCURY_CONTROLS] = controls; }; export const stopMercury = (element) => { const el = element; el[MERCURY_CONTROLS]?.stop(); el[MERCURY_CONTROLS] = undefined; };