related to vuetify#22159
The request: add global config so users (and apps) can override prefers-reduced-motion, exposed via a hook (useReducedMotion()) and a data attribute on <body> for CSS.
Does it fit v0?
v0 already ships usePrefersReducedMotion() utility and the plugin would be a natural extension.
What needs to be covered
- new plugin - similar to useTheme (in how it resolves
prefers-color-scheme)
- transition tokens that read the resolved value (expected in Paper or Vuetify)
Logic input value: mode: 'system' | 'always' | 'never' (reactive).
'system' means resolving media query - same challenge with SSR as for adapting to "system" theme (requires client-hints)
'always'/'never' - user/app preference
Paper/Vuetify are meant to consume the reduced boolean flag
- JS-based animations could pick the readonly
ref from composable or provide/inject
- CSS-based transitions could be branch out behind
[data-reduced-motion="reduce"] to either apply fade in/out or skip transition entiely
Challenges / limitations
- CSS coordination v0 is headless, so the behavior is just a flag. Anything that actually drops a transition lives in Paper / Vuetify / app CSS. The plugin only sets the attribute; consumers must author
@media (prefers-reduced-motion: reduce) and selectors.
- Granularity ON/OFF
[data-reduced-motion="reduce"] and const { current } = useReducedMotion() are meant to be consumed/translated into "keep fades, drop transforms" semantics. VPaper or SCSS/CSS tokens could define the policy.
- SSR + hydration first paint may still flicker unless the app injects tokens server-side
- Naming:
system/always/never (clearer than in Motion user/always/never)
Recommendation
Land useReducedMotion in v0 as a createPlugin-style provider (mirroring useTheme), exposing { mode, reduced, current } and side-effecting document.body.dataset.reducedMotion. Keep policy (what to fade, what to drop) in Paper/Vuetify. The Vuetify-side regression that prompted the issue (v3.10.0) is a separate fix that consumes this primitive.
Sources:
related to vuetify#22159
The request: add global config so users (and apps) can override
prefers-reduced-motion, exposed via a hook (useReducedMotion()) and a data attribute on<body>for CSS.Does it fit v0?
v0 already ships
usePrefersReducedMotion()utility and the plugin would be a natural extension.What needs to be covered
prefers-color-scheme)Logic input value:
mode: 'system' | 'always' | 'never'(reactive).'system'means resolving media query - same challenge with SSR as for adapting to "system" theme (requires client-hints)'always'/'never'- user/app preferencePaper/Vuetify are meant to consume the
reducedboolean flagreffrom composable orprovide/inject[data-reduced-motion="reduce"]to either apply fade in/out or skip transition entielyChallenges / limitations
@media (prefers-reduced-motion: reduce)and selectors.[data-reduced-motion="reduce"]andconst { current } = useReducedMotion()are meant to be consumed/translated into "keep fades, drop transforms" semantics. VPaper or SCSS/CSS tokens could define the policy.system/always/never(clearer than in Motionuser/always/never)Recommendation
Land
useReducedMotionin v0 as acreatePlugin-style provider (mirroringuseTheme), exposing{ mode, reduced, current }and side-effectingdocument.body.dataset.reducedMotion. Keep policy (what to fade, what to drop) in Paper/Vuetify. The Vuetify-side regression that prompted the issue (v3.10.0) is a separate fix that consumes this primitive.Sources: