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.
40 lines
1.1 KiB
40 lines
1.1 KiB
import {
|
|
resolveMotion,
|
|
MOTIONS_INTENT,
|
|
type MotionEffective,
|
|
type MotionIntent
|
|
} from '$libs/motion';
|
|
import type { PrefsDimension } from '$libs/prefs';
|
|
|
|
export interface MotionDimensionOptions {
|
|
readonly intents?: readonly MotionIntent[];
|
|
readonly default?: MotionEffective;
|
|
}
|
|
|
|
/**
|
|
* Built-in motion dimension. Like theme, intent includes `'system'`
|
|
* but effective is narrower (`'allow' | 'reduce'`); the dimension's
|
|
* `resolve` folds intent + `env.reducedMotion` into the effective
|
|
* value.
|
|
*/
|
|
export function motionDimension(
|
|
options: MotionDimensionOptions = {}
|
|
): PrefsDimension<MotionIntent, MotionEffective> {
|
|
const intents = options.intents ?? MOTIONS_INTENT;
|
|
const fallback = options.default ?? 'allow';
|
|
return {
|
|
defaultValue: fallback,
|
|
validate(value) {
|
|
if (typeof value !== 'string') return { ok: false, reason: 'unsupported_motion' };
|
|
if (!intents.includes(value as MotionIntent)) {
|
|
return { ok: false, reason: 'unsupported_motion' };
|
|
}
|
|
return { ok: true, value: value as MotionIntent };
|
|
},
|
|
resolve(intent, env) {
|
|
return resolveMotion(intent, env.reducedMotion, fallback);
|
|
},
|
|
catalog: () => intents
|
|
};
|
|
}
|