feat(MotionPreference): Create common logic to store information about prefers-reduced-motion
This commit is contained in:
37
src/shared/lib/accessibility/motion.svelte.ts
Normal file
37
src/shared/lib/accessibility/motion.svelte.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// Check if we are in a browser environment
|
||||
const isBrowser = typeof window !== 'undefined';
|
||||
|
||||
class MotionPreference {
|
||||
// Reactive state
|
||||
#reduced = $state(false);
|
||||
#mediaQuery: MediaQueryList = new MediaQueryList();
|
||||
|
||||
private handleChange = (e: MediaQueryListEvent) => {
|
||||
this.#reduced = e.matches;
|
||||
};
|
||||
|
||||
constructor() {
|
||||
if (isBrowser) {
|
||||
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
|
||||
|
||||
// Set initial value immediately
|
||||
this.#reduced = mediaQuery.matches;
|
||||
|
||||
mediaQuery.addEventListener('change', this.handleChange);
|
||||
|
||||
this.#mediaQuery = mediaQuery;
|
||||
}
|
||||
}
|
||||
|
||||
// Getter allows us to use 'motion.reduced' reactively in components
|
||||
get reduced() {
|
||||
return this.#reduced;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.#mediaQuery.removeEventListener('change', this.handleChange);
|
||||
}
|
||||
}
|
||||
|
||||
// Export a single instance to be used everywhere
|
||||
export const motion = new MotionPreference();
|
||||
@@ -13,3 +13,5 @@ export {
|
||||
type Virtualizer,
|
||||
type VirtualizerOptions,
|
||||
} from './helpers';
|
||||
|
||||
export { motion } from './accessibility/motion.svelte';
|
||||
|
||||
Reference in New Issue
Block a user