You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/arts/prefs/motion-source.ts

33 lines
1.5 KiB

import { readActivePrefsSlot, type ActivePrefs } from './active-prefs.svelte';
import type { MotionEffective, MotionSource } from '$libs/motion';
/**
* The `motion` slot of an open `ActivePrefs`, as the `MotionSource` port the
* animation runtimes consume.
*
* This is the ONE place the effective reduced-motion value is decided for
* everything downstream: the motion engine, the scene engine, sema's haptic
* channel and every eidos component read it from here, so an explicit
* `motion: 'allow'` reaches them all and a `reduce` degrades them all. Asking
* the OS again (`ActiveDom.prefersReducedMotion`) is asking a question prefs
* has already answered — the media query is an ENVIRONMENT hint, and
* `resolveMotion` folded it with the user's intent long before this call.
*
* The slot is read DEFENSIVELY (the shape `dom-projection.ts` uses): an app is
* free to compose a schema without a `motion` dimension, and the answer then is
* `undefined` — no source, so each consumer keeps its own documented default
* rather than inventing a policy nobody declared.
*
* Reads go through `slot.get()` on every call: the slot is `$state`-backed, so
* a caller inside a `$derived` / `$effect` tracks it, and a caller outside one
* still sees the current value.
*/
export function createMotionSourceFromPrefs(prefs: ActivePrefs): MotionSource | undefined {
const slot = readActivePrefsSlot<MotionEffective>(prefs, 'motion');
if (!slot) return undefined;
return {
get: () => slot.get(),
onChange: (handler) => slot.onChange(handler)
};
}

Powered by TurnKey Linux.