aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/components/usePrefersReducedMotion.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'docs/components/usePrefersReducedMotion.tsx')
-rw-r--r--docs/components/usePrefersReducedMotion.tsx44
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;
+}