diff options
Diffstat (limited to 'docs/components/usePrefersReducedMotion.tsx')
| -rw-r--r-- | docs/components/usePrefersReducedMotion.tsx | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/docs/components/usePrefersReducedMotion.tsx b/docs/components/usePrefersReducedMotion.tsx new file mode 100644 index 0000000..dd9d82c --- /dev/null +++ b/docs/components/usePrefersReducedMotion.tsx @@ -0,0 +1,44 @@ +import { useState, useEffect } from "react"; + +const QUERY = "(prefers-reduced-motion: no-preference)"; +const isRenderingOnServer = typeof window === "undefined"; +/** + * All code here from https://www.joshwcomeau.com/snippets/react-hooks/use-prefers-reduced-motion/ + */ +const getInitialState = () => { + // For our initial server render, we won't know if the user + // prefers reduced motion, but it doesn't matter. This value + // will be overwritten on the client, before any animations + // occur. + return isRenderingOnServer ? true : !window.matchMedia(QUERY).matches; +}; + +/** + * Checks the user's device setting for `prefers-reduced-motion`. + * Use this if you can't use a media query in CSS. + * + * From https://www.joshwcomeau.com/snippets/react-hooks/use-prefers-reduced-motion/ + */ +export function usePrefersReducedMotion(): boolean { + const [prefersReducedMotion, setPrefersReducedMotion] = + useState(getInitialState); + useEffect(() => { + const mediaQueryList = window.matchMedia(QUERY); + const listener = (event: MediaQueryListEvent) => { + setPrefersReducedMotion(!event.matches); + }; + if (mediaQueryList.addEventListener) { + mediaQueryList.addEventListener("change", listener); + } else { + mediaQueryList.addListener(listener); + } + return () => { + if (mediaQueryList.removeEventListener) { + mediaQueryList.removeEventListener("change", listener); + } else { + mediaQueryList.removeListener(listener); + } + }; + }, []); + return prefersReducedMotion; +} |
