@scaleway/use-media
Version:
A small hook to track CSS media query state
44 lines (43 loc) • 1.18 kB
JavaScript
import { useState, useEffect, useLayoutEffect } from "react";
function noop() {
}
const mockMediaQueryList = {
addEventListener: noop,
addListener: noop,
dispatchEvent: (
/* istanbul ignore next */
() => true
),
matches: false,
media: "",
onchange: noop,
removeEventListener: noop,
removeListener: noop
};
const createUseMedia = (effect) => (query, defaultState = false) => {
const [state, setState] = useState(defaultState);
effect(() => {
let mounted = true;
const mediaQueryList = typeof window !== "undefined" && typeof window.matchMedia === "undefined" ? mockMediaQueryList : window.matchMedia(query);
const onChange = () => {
if (!mounted) {
return;
}
setState(Boolean(mediaQueryList.matches));
};
mediaQueryList.addEventListener("change", onChange);
setState(mediaQueryList.matches);
return () => {
mounted = false;
mediaQueryList.removeEventListener("change", onChange);
};
}, [query]);
return state;
};
const useMedia = createUseMedia(useEffect);
const useMediaLayout = createUseMedia(useLayoutEffect);
export {
mockMediaQueryList,
useMedia,
useMediaLayout
};