Tailwind CSSのbreakpointsに基づいたMediaQueryのReact hooksを作る
Published at
動機
- Tailwind CSS の breakpoints の設定値に基づいて見せ方を変えたい
- Tailwindのクラスを利用するときに指定する
sm:
やmd:
といったブレイクポイントと同期してほしい
解法
css - How do I get Tailwind's active breakpoint in JavaScript? - Stack Overflow を参考にした。
Tailwindのconfigを解決して、matchMediaのパラメータとして利用する。
import { useEffect, useState } from "react";
import resolveConfig from "tailwindcss/resolveConfig";
import config from "path/to/tailwind.config";
const breakpoints = resolveConfig(config).theme.screens;
type Key = keyof typeof breakpoints;
const createMediaQueryList = <K extends Key>(key: K) =>
window.matchMedia(`(min-width: ${breakpoints[key]})`);
const useMediaQuery = <K extends Key>(key: K) => {
const [matches, setMatches] = useState<boolean>(
createMediaQueryList(key).matches,
);
useEffect(() => {
const mediaQueryList = createMediaQueryList(key);
const handler = (e: MediaQueryListEvent) => setMatches(e.matches);
mediaQueryList.addEventListener("change", handler);
return () => {
mediaQueryList.removeEventListener("change", handler);
};
}, [key]);
return matches;
};
// 利用するとき
const isSmall = useMediaQuery("sm");
RSCが有効な環境ではwindow
を参照できないのでuseState
の引数は適宜useEffect
の中に移動するなどする。