UNPKG

2.36 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.default = useMediaQuery;
5
6var _useIsomorphicEffect = _interopRequireDefault(require("./useIsomorphicEffect"));
7
8var _react = require("react");
9
10function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
12var matchersByWindow = new WeakMap();
13
14var getMatcher = function getMatcher(query, targetWindow) {
15 if (!query || !targetWindow) return undefined;
16 var matchers = matchersByWindow.get(targetWindow) || new Map();
17 matchersByWindow.set(targetWindow, matchers);
18 var mql = matchers.get(query);
19
20 if (!mql) {
21 mql = targetWindow.matchMedia(query);
22 mql.refCount = 0;
23 matchers.set(mql.media, mql);
24 }
25
26 return mql;
27};
28/**
29 * Match a media query and get updates as the match changes. The media string is
30 * passed directly to `window.matchMedia` and run as a Layout Effect, so initial
31 * matches are returned before the browser has a chance to paint.
32 *
33 * ```tsx
34 * function Page() {
35 * const isWide = useMediaQuery('min-width: 1000px')
36 *
37 * return isWide ? "very wide" : 'not so wide'
38 * }
39 * ```
40 *
41 * Media query lists are also reused globally, hook calls for the same query
42 * will only create a matcher once under the hood.
43 *
44 * @param query A media query
45 * @param targetWindow The window to match against, uses the globally available one as a default.
46 */
47
48
49function useMediaQuery(query, targetWindow) {
50 if (targetWindow === void 0) {
51 targetWindow = typeof window === 'undefined' ? undefined : window;
52 }
53
54 var mql = getMatcher(query, targetWindow);
55
56 var _useState = (0, _react.useState)(function () {
57 return mql ? mql.matches : false;
58 }),
59 matches = _useState[0],
60 setMatches = _useState[1];
61
62 (0, _useIsomorphicEffect.default)(function () {
63 var mql = getMatcher(query, targetWindow);
64
65 if (!mql) {
66 return setMatches(false);
67 }
68
69 var matchers = matchersByWindow.get(targetWindow);
70
71 var handleChange = function handleChange() {
72 setMatches(mql.matches);
73 };
74
75 mql.refCount++;
76 mql.addListener(handleChange);
77 handleChange();
78 return function () {
79 mql.removeListener(handleChange);
80 mql.refCount--;
81
82 if (mql.refCount <= 0) {
83 matchers == null ? void 0 : matchers.delete(mql.media);
84 }
85
86 mql = undefined;
87 };
88 }, [query]);
89 return matches;
90}
\No newline at end of file