Created
January 4, 2021 20:50
-
-
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.
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 { 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 |
@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
broken link?