chore: switch to use of svelte native prefersReducedMotion media

This commit is contained in:
Ilia Mashkov
2026-01-22 15:33:38 +03:00
parent b41c48da67
commit e4970e43ba
4 changed files with 7 additions and 39 deletions

View File

@@ -6,9 +6,9 @@
- Adds smooth transition when font appears - Adds smooth transition when font appears
--> -->
<script lang="ts"> <script lang="ts">
import { motion } from '$shared/lib';
import { cn } from '$shared/shadcn/utils/shadcn-utils'; import { cn } from '$shared/shadcn/utils/shadcn-utils';
import type { Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import { prefersReducedMotion } from 'svelte/motion';
import { appliedFontsManager } from '../../model'; import { appliedFontsManager } from '../../model';
interface Props { interface Props {
@@ -59,7 +59,7 @@ const status = $derived(appliedFontsManager.getFontStatus(id, weight, false));
const shouldReveal = $derived(hasEnteredViewport && (status === 'loaded' || status === 'error')); const shouldReveal = $derived(hasEnteredViewport && (status === 'loaded' || status === 'error'));
const transitionClasses = $derived( const transitionClasses = $derived(
motion.reduced prefersReducedMotion.current
? 'transition-none' // Disable CSS transitions if motion is reduced ? 'transition-none' // Disable CSS transitions if motion is reduced
: 'transition-all duration-700 ease-[cubic-bezier(0.22,1,0.36,1)]', : 'transition-all duration-700 ease-[cubic-bezier(0.22,1,0.36,1)]',
); );
@@ -71,8 +71,9 @@ const transitionClasses = $derived(
class={cn( class={cn(
transitionClasses, transitionClasses,
// If reduced motion is on, we skip the transform/blur entirely // If reduced motion is on, we skip the transform/blur entirely
!shouldReveal && !motion.reduced && 'opacity-0 translate-y-8 scale-[0.98] blur-sm', !shouldReveal && !prefersReducedMotion.current
!shouldReveal && motion.reduced && 'opacity-0', // Still hide until font is ready, but no movement && 'opacity-0 translate-y-8 scale-[0.98] blur-sm',
!shouldReveal && prefersReducedMotion.current && 'opacity-0', // Still hide until font is ready, but no movement
shouldReveal && 'opacity-100 translate-y-0 scale-100 blur-0', shouldReveal && 'opacity-100 translate-y-0 scale-100 blur-0',
className, className,
)} )}

View File

@@ -1,32 +0,0 @@
// Check if we are in a browser environment
const isBrowser = typeof window !== 'undefined';
// A class to manage motion preference and provide a single instance for use everywhere
class MotionPreference {
// Reactive state
#reduced = $state(false);
constructor() {
if (isBrowser) {
const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
// Set initial value immediately
this.#reduced = mediaQuery.matches;
// Simple listener that updates the reactive state
const handleChange = (e: MediaQueryListEvent) => {
this.#reduced = e.matches;
};
mediaQuery.addEventListener('change', handleChange);
}
}
// Getter allows us to use 'motion.reduced' reactively in components
get reduced() {
return this.#reduced;
}
}
// Export a single instance to be used everywhere
export const motion = new MotionPreference();

View File

@@ -19,5 +19,4 @@ export {
type VirtualizerOptions, type VirtualizerOptions,
} from './helpers'; } from './helpers';
export { motion } from './accessibility/motion.svelte';
export { splitArray } from './utils'; export { splitArray } from './utils';

View File

@@ -9,7 +9,6 @@
--> -->
<script lang="ts"> <script lang="ts">
import type { Filter } from '$shared/lib'; import type { Filter } from '$shared/lib';
import { motion } from '$shared/lib';
import { Badge } from '$shared/shadcn/ui/badge'; import { Badge } from '$shared/shadcn/ui/badge';
import { buttonVariants } from '$shared/shadcn/ui/button'; import { buttonVariants } from '$shared/shadcn/ui/button';
import { Checkbox } from '$shared/shadcn/ui/checkbox'; import { Checkbox } from '$shared/shadcn/ui/checkbox';
@@ -20,6 +19,7 @@ import {
import { Label } from '$shared/shadcn/ui/label'; import { Label } from '$shared/shadcn/ui/label';
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down'; import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
import { cubicOut } from 'svelte/easing'; import { cubicOut } from 'svelte/easing';
import { prefersReducedMotion } from 'svelte/motion';
import { slide } from 'svelte/transition'; import { slide } from 'svelte/transition';
interface PropertyFilterProps { interface PropertyFilterProps {
@@ -37,7 +37,7 @@ let isOpen = $state(true);
// Animation config respects user preferences - zero duration if reduced motion enabled // Animation config respects user preferences - zero duration if reduced motion enabled
// Local modifier prevents animation on initial render, only animates user interactions // Local modifier prevents animation on initial render, only animates user interactions
const slideConfig = $derived({ const slideConfig = $derived({
duration: motion.reduced ? 0 : 250, duration: prefersReducedMotion.current ? 0 : 250,
easing: cubicOut, easing: cubicOut,
}); });