<unsweets />

Frontend <3

Tailwind CSSのbreakpointsに基づいたMediaQueryのReact hooksを作る

動機

解法

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の中に移動するなどする。