-
-
Save parkournick3/6d88dad60b83dbb30a99c08955b76a98 to your computer and use it in GitHub Desktop.
React (and NextJS, Typescript) Hook which returns the current TailwindCSS breakpoint size based on the current window width.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useEffect, useState } from 'react' | |
import throttle from 'lodash.throttle' | |
import resolveConfig from 'tailwindcss/resolveConfig' | |
import tailwindConfig from '../../tailwind.config' | |
type Breakpoint = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | |
const findKeyByValue = (object: { [x: string]: unknown }, value: string) => | |
Object.keys(object).find((key) => object[key] === value) | |
const getDeviceConfig = (width: number): Breakpoint => { | |
const fullConfig = resolveConfig(tailwindConfig) | |
const { screens } = fullConfig.theme | |
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | |
/* @ts-ignore */ | |
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument | |
const bpSizes = Object.keys(screens).map((screenSize) => parseInt(screens[screenSize])) | |
const bpShapes = bpSizes.map((size, index) => ({ | |
min: !index ? 0 : bpSizes[index - 1], | |
max: size, | |
key: findKeyByValue(screens, `${size}px`), | |
})) | |
let breakpoint: Breakpoint | null = 'md' | |
bpShapes.forEach((shape) => { | |
if (!shape.min && width < shape.max) { | |
breakpoint = shape.key as Breakpoint | |
} else if (shape.min && width >= shape.min && width < shape.max) { | |
breakpoint = shape.key as Breakpoint | |
} else if (!shape.max && width >= shape.max) { | |
breakpoint = shape.key as Breakpoint | |
} | |
}) | |
return breakpoint | |
} | |
export const useTailwindBreakpoint = () => { | |
const [dimensions, setDimensions] = useState({ | |
width: typeof window !== 'undefined' ? window.innerWidth : 0, | |
height: typeof window !== 'undefined' ? window.innerHeight : 0, | |
}) | |
const handleResize = throttle(function () { | |
setDimensions({ | |
width: typeof window !== 'undefined' ? window.innerWidth : 0, | |
height: typeof window !== 'undefined' ? window.innerHeight : 0, | |
}) | |
}, 200) | |
useEffect(() => { | |
window.addEventListener('resize', handleResize, false) | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, []) | |
return getDeviceConfig(dimensions.width) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment