Skip to content

Instantly share code, notes, and snippets.

@SimeonGriggs
Created January 4, 2021 20:50
Show Gist options
  • Save SimeonGriggs/7071958b8a629faf9137734aec713a0c to your computer and use it in GitHub Desktop.
Save SimeonGriggs/7071958b8a629faf9137734aec713a0c to your computer and use it in GitHub Desktop.
React Hook which returns the current TailwindCSS breakpoint size based on the current window width.
import { useState, useEffect } from 'react'
import resolveConfig from 'tailwindcss/resolveConfig'
import throttle from 'lodash.throttle'
import tailwindConfig from '../tailwind.config.js'
const findKeyByValue = (object, value) =>
Object.keys(object).find((key) => object[key] === value)
const getDeviceConfig = (width) => {
const fullConfig = resolveConfig(tailwindConfig)
const { screens } = fullConfig.theme
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 = null
bpShapes.forEach((shape) => {
if (!shape.min && width < shape.max) {
breakpoint = shape.key
} else if (width >= shape.min && width < shape.max) {
breakpoint = shape.key
} else if (!shape.max && width >= shape.max) {
breakpoint = shape.key
}
})
return breakpoint
}
const useTailwindBreakpoint = () => {
const width = typeof window !== 'undefined' ? window.innerWidth : 0
const [brkPnt, setBrkPnt] = useState(() => getDeviceConfig(width))
useEffect(() => {
const calcInnerWidth = throttle(function () {
setBrkPnt(getDeviceConfig(width))
}, 200)
window.addEventListener('resize', calcInnerWidth)
return () => window.removeEventListener('resize', calcInnerWidth)
}, [])
return brkPnt
}
export default useTailwindBreakpoint
@parkournick3
Copy link

parkournick3 commented May 27, 2023

@dnlaviv
Copy link

dnlaviv commented Jan 27, 2024

My Nextjs ( and Typescript ) version https://gist.github.com/parkournick00110010/6d88dad60b83dbb30a99c08955b76a98

broken link?

@DrChai
Copy link

DrChai commented Mar 10, 2024

@dnlaviv here is my typescript version, it uses MediaQueryListEvent event instead for the best performance:

import resolveConfig from "tailwindcss/resolveConfig";
import tailwindConfig from "@/tailwind.config";
import { useEffect, useState } from "react";

const fullConfig = resolveConfig(tailwindConfig);
const {
  theme: { screens },
} = fullConfig;
export default (query: keyof typeof screens): boolean => {
  const mediaQuery = `(min-width: ${screens[query]})`;
  const matchQueryList = window.matchMedia(mediaQuery);
  const [isMatch, setMatch] = useState<boolean>(false);
  const onChange = (e: MediaQueryListEvent) => setMatch(e.matches);
  useEffect(() => {
    setMatch(matchQueryList.matches);
    matchQueryList.addEventListener("change", onChange);
    return () => matchQueryList.removeEventListener("change", onChange);
  }, [query]);
  return isMatch;
}

That's much about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment