Files
La-Fabrik/src/hooks/ui/usePrefersReducedMotion.ts
T
Tom Boullay 0f6860f1ae refactor(site): extract shared utilities and centralise dialogue IDs
- new src/hooks/ui/useIsMobile.ts (matchMedia + useSyncExternalStore)
  replacing the resize-handler hook inlined inside pages/site/page.tsx
- new src/hooks/ui/usePrefersReducedMotion.ts
- new src/data/site/dialogueIds.ts so site and intro components stop
  carrying hard-coded narrator IDs
- siteConfig: add SITE_BACKGROUND_STYLE shared by SiteLayout and
  SiteMobileBlocker, rename forcedName to presetPlayerName, fix the
  swapped id/label pairing on situation cards
- useSiteStore: rename selectedExperience/Situation to *Index so the
  stored value (an array index) is obvious in callers
- audioConfig: drop dead AUDIO_PATHS placeholders
- propagate the renames and SITE_BACKGROUND_STYLE through SiteLayout,
  SiteWelcomeScreen, SiteSituationScreen and pages/site/page.tsx
2026-05-30 18:43:35 +02:00

30 lines
864 B
TypeScript

import { useSyncExternalStore } from "react";
const REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
function subscribeToReducedMotion(callback: () => void): () => void {
const query = window.matchMedia(REDUCED_MOTION_QUERY);
query.addEventListener("change", callback);
return () => query.removeEventListener("change", callback);
}
function getReducedMotionSnapshot(): boolean {
return window.matchMedia(REDUCED_MOTION_QUERY).matches;
}
function getServerReducedMotionSnapshot(): boolean {
return false;
}
/**
* True when the user has requested reduced motion at the OS level.
* UI fades and transitions should collapse to 0ms when this is true.
*/
export function usePrefersReducedMotion(): boolean {
return useSyncExternalStore(
subscribeToReducedMotion,
getReducedMotionSnapshot,
getServerReducedMotionSnapshot,
);
}