Skip to content

Instantly share code, notes, and snippets.

@kosciolek
Created June 20, 2021 17:39
Show Gist options
  • Save kosciolek/b98fd24142d5081427618afb7794f420 to your computer and use it in GitHub Desktop.
Save kosciolek/b98fd24142d5081427618afb7794f420 to your computer and use it in GitHub Desktop.
import {useEffect, useState} from "react";
import {firstToUppercase} from "../utils/js";
export const breakpoints = {
xs: "0px",
sm: "600px",
md: "960px",
lg: "1280px",
xl: "1920px",
};
export const query = Object.entries(breakpoints).reduce(
(acc, [breakpoint, value]) => {
acc[breakpoint] = `@media screen and (min-width: ${value})`;
acc[`useQuery${firstToUppercase(breakpoint)}`] = () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [matches, setMatches] = useState(true);
// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => {
if (typeof window === undefined) return () => {};
const mediaQuery = window.matchMedia(`screen and (min-width: ${value})`);
const listener = ev => {
setMatches(ev.matches);
};
mediaQuery.addEventListener("change", listener);
return () => {
mediaQuery.removeEventListener("change", listener);
}
}, []);
return matches;
};
return acc;
},
{} as {
[K in keyof typeof breakpoints]: `@media screen and (min-width: ${typeof breakpoints[K]})`;
} & {[K in keyof typeof breakpoints as `useQuery${Capitalize<K>}`]: () => boolean;}
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment