{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "use-prefers-reduced-motion", "title": "usePrefersReducedMotion", "author": "Piergiorgio Gonni ", "description": "Tracks the prefers-reduced-motion media query without tripping hydration.", "files": [ { "path": "registry/shad-fx/use-prefers-reduced-motion.ts", "content": "\"use client\";\n\nimport { useSyncExternalStore } from \"react\";\n\nconst QUERY = \"(prefers-reduced-motion: reduce)\";\n\nfunction subscribe(onChange: () => void) {\n\tconst query = window.matchMedia(QUERY);\n\tquery.addEventListener(\"change\", onChange);\n\treturn () => query.removeEventListener(\"change\", onChange);\n}\n\nconst getSnapshot = () => window.matchMedia(QUERY).matches;\n\n/**\n * Read through useSyncExternalStore rather than a state initializer or a ref:\n * the server has no `matchMedia`, so React renders against a stable `false`\n * snapshot and picks up the real value — and later changes to it — on the client.\n */\nexport function usePrefersReducedMotion() {\n\treturn useSyncExternalStore(subscribe, getSnapshot, () => false);\n}\n", "type": "registry:hook", "target": "@hooks/use-prefers-reduced-motion.ts" } ], "categories": [ "hooks", "accessibility" ], "type": "registry:hook" }