import { useSyncExternalStore } from "react"; /** The reader asked the system for less motion (Windows also reports it whenever its animation * effects are off). One spelling for the hook and for a one-off `matchMedia` read alike. */ export const REDUCED_MOTION = "(prefers-reduced-motion: reduce)"; /** Whether a CSS media query matches, live. For a component that must RENDER differently at a * breakpoint rather than merely hide one of two renders with CSS (`ui/DataTable` mounted its table * AND its card list at every width: double the DOM, duplicate ids and keyboard targets). Where * `matchMedia` is missing (jsdom) it answers `fallback`. */ export function useMediaQuery(query: string, fallback = true): boolean { return useSyncExternalStore( (onChange) => { if (typeof window.matchMedia !== "function") return () => {}; const mql = window.matchMedia(query); mql.addEventListener("change", onChange); return () => mql.removeEventListener("change", onChange); }, () => (typeof window.matchMedia === "function" ? window.matchMedia(query).matches : fallback), () => fallback, ); }