@react-hookz/web
Version:
React hooks done right, for browser and SSR.
62 lines (61 loc) • 2.05 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMediaQuery = void 0;
var react_1 = require("react");
var __1 = require("..");
var queriesMap = new Map();
var querySubscribe = function (query, setState) {
var entry = queriesMap.get(query);
if (!entry) {
var mql_1 = matchMedia(query);
var dispatchers_1 = new Set();
var listener = function () {
dispatchers_1.forEach(function (d) { return d(mql_1.matches); });
};
if (mql_1.addEventListener)
mql_1.addEventListener('change', listener, { passive: true });
else
mql_1.addListener(listener);
entry = {
mql: mql_1,
dispatchers: dispatchers_1,
listener: listener,
};
queriesMap.set(query, entry);
}
entry.dispatchers.add(setState);
setState(entry.mql.matches);
};
var queryUnsubscribe = function (query, setState) {
var entry = queriesMap.get(query);
// else path is impossible to test in normal situation
/* istanbul ignore else */
if (entry) {
var mql = entry.mql, dispatchers = entry.dispatchers, listener = entry.listener;
dispatchers.delete(setState);
if (!dispatchers.size) {
queriesMap.delete(query);
if (mql.removeEventListener)
mql.removeEventListener('change', listener);
else
mql.removeListener(listener);
}
}
};
/**
* Tracks the state of CSS media query.
*
* Return undefined initially and later receives correct value.
*
* @param query CSS media query to track.
*/
function useMediaQuery(query) {
var _a = (0, __1.useSafeState)(), state = _a[0], setState = _a[1];
(0, react_1.useEffect)(function () {
querySubscribe(query, setState);
return function () { return queryUnsubscribe(query, setState); };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [query]);
return state;
}
exports.useMediaQuery = useMediaQuery;