UNPKG

2.51 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import * as React from 'react';
3import { getThemeProps, useTheme } from '@material-ui/styles';
4export default function useMediaQuery(queryInput, options = {}) {
5 const theme = useTheme();
6 const props = getThemeProps({
7 theme,
8 name: 'MuiUseMediaQuery',
9 props: {}
10 });
11
12 if (process.env.NODE_ENV !== 'production') {
13 if (typeof queryInput === 'function' && theme === null) {
14 console.error(['Material-UI: The `query` argument provided is invalid.', 'You are providing a function without a theme in the context.', 'One of the parent elements needs to use a ThemeProvider.'].join('\n'));
15 }
16 }
17
18 let query = typeof queryInput === 'function' ? queryInput(theme) : queryInput;
19 query = query.replace(/^@media( ?)/m, ''); // Wait for jsdom to support the match media feature.
20 // All the browsers Material-UI support have this built-in.
21 // This defensive check is here for simplicity.
22 // Most of the time, the match media logic isn't central to people tests.
23
24 const supportMatchMedia = typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined';
25
26 const {
27 defaultMatches = false,
28 matchMedia = supportMatchMedia ? window.matchMedia : null,
29 noSsr = false,
30 ssrMatchMedia = null
31 } = _extends({}, props, options);
32
33 const [match, setMatch] = React.useState(() => {
34 if (noSsr && supportMatchMedia) {
35 return matchMedia(query).matches;
36 }
37
38 if (ssrMatchMedia) {
39 return ssrMatchMedia(query).matches;
40 } // Once the component is mounted, we rely on the
41 // event listeners to return the correct matches value.
42
43
44 return defaultMatches;
45 });
46 React.useEffect(() => {
47 let active = true;
48
49 if (!supportMatchMedia) {
50 return undefined;
51 }
52
53 const queryList = matchMedia(query);
54
55 const updateMatch = () => {
56 // Workaround Safari wrong implementation of matchMedia
57 // TODO can we remove it?
58 // https://github.com/mui-org/material-ui/pull/17315#issuecomment-528286677
59 if (active) {
60 setMatch(queryList.matches);
61 }
62 };
63
64 updateMatch();
65 queryList.addListener(updateMatch);
66 return () => {
67 active = false;
68 queryList.removeListener(updateMatch);
69 };
70 }, [query, matchMedia, supportMatchMedia]);
71
72 if (process.env.NODE_ENV !== 'production') {
73 // eslint-disable-next-line react-hooks/rules-of-hooks
74 React.useDebugValue({
75 query,
76 match
77 });
78 }
79
80 return match;
81}
\No newline at end of file