Respect Reduced Motion Preference
Problem
Animation behavior must respond when the operating-system motion preference changes. createMediaQuery() exposes the current match as reactive state.
Solution
Synchronize a document class and handle environments without matchMedia.
ts
import { createMediaQuery, SentinelUnavailableError } from '@vielzeug/sentinel';
function observeReducedMotion(): () => void {
try {
const reducedMotion = createMediaQuery('(prefers-reduced-motion: reduce)');
const render = () => {
document.documentElement.classList.toggle('reduce-motion', reducedMotion.value.matches);
};
render();
const unsubscribe = reducedMotion.subscribe(render);
return () => {
unsubscribe();
reducedMotion.dispose();
};
} catch (error) {
if (!(error instanceof SentinelUnavailableError)) throw error;
return () => {};
}
}
const stopObserving = observeReducedMotion();
// Call stopObserving() when the owning view unmounts.Pitfalls
- Keep the default experience usable when
matchMediais unavailable. - Apply the initial state before waiting for the first change.
- Prefer CSS
@media (prefers-reduced-motion: reduce)when JavaScript does not need the value.