import { useEffect, useState } from "react"; /** * Shared (free-eligible) prefers-reduced-motion helpers. * * Lives OUTSIDE src/frontend/extension/ so the free renderer no longer lacks the * reduced-motion check that previously only existed inside ExtensionSwatchGroup. * Used to gate the one fixed select micro-interaction (WCAG 2.3.3 / 1.4.1). */ const QUERY = "(prefers-reduced-motion: reduce)"; /** Synchronous, SSR-safe read of the reduced-motion preference. */ export function prefersReducedMotion(): boolean { if ( typeof window === "undefined" || typeof window.matchMedia !== "function" ) { return false; } try { return window.matchMedia(QUERY).matches; } catch { return false; } } /** React hook that tracks the reduced-motion preference and updates on change. */ export function useReducedMotion(): boolean { const [reduced, setReduced] = useState(prefersReducedMotion); useEffect(() => { if ( typeof window === "undefined" || typeof window.matchMedia !== "function" ) { return; } const mql = window.matchMedia(QUERY); const onChange = (): void => setReduced(mql.matches); // Keep state in sync immediately in case it changed before the effect ran. onChange(); if (typeof mql.addEventListener === "function") { mql.addEventListener("change", onChange); return () => mql.removeEventListener("change", onChange); } // Safari < 14 fallback. mql.addListener(onChange); return () => mql.removeListener(onChange); }, []); return reduced; }