import { useCallback, useEffect, useRef, useState } from "react"; export const breakpoints = { sm: 640, md: 768, lg: 1024, xl: 1280, "2xl": 1536, }; export type Breakpoint = keyof typeof breakpoints; export const breakpointKeys = Object.keys(breakpoints); export const breakpointValues = Object.values(breakpoints); export const useBreakpoint = (onChange?: (breakpoint: number) => void) => { const prevRef = useRef(0); const [curBreakpoint, setBreakpoint] = useState( getScreenBreakpoint() ); const onResize = useCallback(() => { const breakpointIdx = getScreenBreakpoint(); if (breakpointIdx >= 0 && prevRef.current !== breakpointIdx) { if (onChange) { onChange(breakpointIdx); } else { setBreakpoint(breakpointIdx); } prevRef.current = breakpointIdx; } }, [onChange]); useEffect(() => { window.addEventListener("resize", onResize); onResize(); return () => { window.removeEventListener("resize", onResize); }; }, [onResize]); const breakpoint = breakpointKeys[curBreakpoint]; return [curBreakpoint, breakpoint] as [number, Breakpoint]; }; export function getScreenBreakpoint() { const width = typeof window !== "undefined" ? window.innerWidth : 0; let breakpointIdx = breakpointValues.findIndex((i) => width <= i); if (breakpointIdx < 0) { breakpointIdx = breakpointKeys.length - 1; } return breakpointIdx; }