From ab4fd7747175a51e985e93570cd50082c29f1176 Mon Sep 17 00:00:00 2001 From: Carter Date: Wed, 13 Nov 2024 14:00:04 -0600 Subject: [PATCH] added useWidth hook --- src/hooks/useWidth.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/hooks/useWidth.ts diff --git a/src/hooks/useWidth.ts b/src/hooks/useWidth.ts new file mode 100644 index 0000000..1c20a48 --- /dev/null +++ b/src/hooks/useWidth.ts @@ -0,0 +1,27 @@ +import { Breakpoint, Theme, useTheme } from "@mui/material/styles"; +import useMediaQuery from "@mui/material/useMediaQuery"; + +type BreakpointOrNull = Breakpoint | null; + +/** + * Be careful using this hook. It only works because the number of + * breakpoints in theme is static. It will break once you change the number of + * breakpoints. See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level + */ +export function useWidth() { + const theme: Theme = useTheme(); + const keys: Breakpoint[] = [...theme.breakpoints.keys].reverse(); + return ( + keys.reduce((output: BreakpointOrNull, key: Breakpoint) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const matches = useMediaQuery(theme.breakpoints.up(key)); + return !output && matches ? key : output; + }, null) || "xs" + ); +} + +// useWidth wrapper that just tells you if you're in a mobile view or not given a set or +// using a standard set of "mobile" breakpoints. The same warnings as useWidth apply. +export function useMobile() { + return useWidth() === "xs"; +}