Skip to content

Instantly share code, notes, and snippets.

@KristofferEriksson
Created February 2, 2024 10:55
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save KristofferEriksson/6dc771f8933025c68ba8a4d30de56858 to your computer and use it in GitHub Desktop.
Save KristofferEriksson/6dc771f8933025c68ba8a4d30de56858 to your computer and use it in GitHub Desktop.
React hook for triggering effects when layout changes due to Tailwind breakpoints
import { useEffect, useState } from "react";
import resolveConfig from "tailwindcss/resolveConfig";
// Update the path to your Tailwind config file
import tailwindConfig from "tailwind.config";
const useTailwindBreakpoint = ({
onBreakpointChange,
}: {
// eslint-disable-next-line no-unused-vars
onBreakpointChange?: (breakpoint: string) => void;
} = {}): string => {
const fullConfig = resolveConfig(tailwindConfig);
const breakpoints: { [key: string]: string } = fullConfig.theme.screens;
// Sort breakpoints by size and get the smallest one
const sortedBreakpoints = Object.keys(breakpoints).sort(
(a, b) =>
parseInt(breakpoints[a] as string, 10) -
parseInt(breakpoints[b] as string, 10)
);
const smallestBreakpoint = sortedBreakpoints[0] as string;
const [currentBreakpoint, setCurrentBreakpoint] = useState<string>("");
useEffect(() => {
let debounceTimeout: ReturnType<typeof setTimeout>;
const checkBreakpoint = () => {
const matchedBreakpoints = Object.keys(breakpoints).filter(
(breakpoint) => {
const breakpointValue = breakpoints[breakpoint] as string;
const breakpointSize = parseInt(breakpointValue, 10);
return !isNaN(breakpointSize) && window.innerWidth >= breakpointSize;
}
);
const newBreakpoint = matchedBreakpoints.pop() || smallestBreakpoint;
if (newBreakpoint !== currentBreakpoint) {
setCurrentBreakpoint(newBreakpoint);
if (onBreakpointChange) {
onBreakpointChange(newBreakpoint);
}
}
};
checkBreakpoint();
const debouncedCheckBreakpoint = () => {
clearTimeout(debounceTimeout);
debounceTimeout = setTimeout(checkBreakpoint, 100);
};
window.addEventListener("resize", debouncedCheckBreakpoint);
return () => {
window.removeEventListener("resize", debouncedCheckBreakpoint);
clearTimeout(debounceTimeout);
};
}, [breakpoints, currentBreakpoint, onBreakpointChange]);
return currentBreakpoint;
};
export default useTailwindBreakpoint;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment