UNPKG

@mui/material

Version:

Quickly build beautiful React apps. MUI is a simple and customizable component library to build faster, beautiful, and more accessible React applications. Follow your own design system, or start with Material Design.

136 lines (108 loc) 5.68 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useMediaQuery; var React = _interopRequireWildcard(require("react")); var _system = require("@mui/system"); var _useEnhancedEffect = _interopRequireDefault(require("../utils/useEnhancedEffect")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function useMediaQueryOld(query, defaultMatches, matchMedia, ssrMatchMedia, noSsr) { const supportMatchMedia = typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined'; const [match, setMatch] = React.useState(() => { if (noSsr && supportMatchMedia) { return matchMedia(query).matches; } if (ssrMatchMedia) { return ssrMatchMedia(query).matches; } // Once the component is mounted, we rely on the // event listeners to return the correct matches value. return defaultMatches; }); (0, _useEnhancedEffect.default)(() => { let active = true; if (!supportMatchMedia) { return undefined; } const queryList = matchMedia(query); const updateMatch = () => { // Workaround Safari wrong implementation of matchMedia // TODO can we remove it? // https://github.com/mui-org/material-ui/pull/17315#issuecomment-528286677 if (active) { setMatch(queryList.matches); } }; updateMatch(); // TODO: Use `addEventListener` once support for Safari < 14 is dropped queryList.addListener(updateMatch); return () => { active = false; queryList.removeListener(updateMatch); }; }, [query, matchMedia, supportMatchMedia]); return match; } // eslint-disable-next-line no-useless-concat -- Workaround for https://github.com/webpack/webpack/issues/14814 const maybeReactUseSyncExternalStore = React['useSyncExternalStore' + '']; function useMediaQueryNew(query, defaultMatches, matchMedia, ssrMatchMedia) { const getDefaultSnapshot = React.useCallback(() => defaultMatches, [defaultMatches]); const getServerSnapshot = React.useMemo(() => { if (ssrMatchMedia !== null) { const { matches } = ssrMatchMedia(query); return () => matches; } return getDefaultSnapshot; }, [getDefaultSnapshot, query, ssrMatchMedia]); const [getSnapshot, subscribe] = React.useMemo(() => { if (matchMedia === null) { return [getDefaultSnapshot, () => () => {}]; } const mediaQueryList = matchMedia(query); return [() => mediaQueryList.matches, notify => { // TODO: Use `addEventListener` once support for Safari < 14 is dropped mediaQueryList.addListener(notify); return () => { mediaQueryList.removeListener(notify); }; }]; }, [getDefaultSnapshot, matchMedia, query]); const match = maybeReactUseSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); return match; } function useMediaQuery(queryInput, options = {}) { const theme = (0, _system.useThemeWithoutDefault)(); // Wait for jsdom to support the match media feature. // All the browsers MUI support have this built-in. // This defensive check is here for simplicity. // Most of the time, the match media logic isn't central to people tests. const supportMatchMedia = typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined'; const { defaultMatches = false, matchMedia = supportMatchMedia ? window.matchMedia : null, ssrMatchMedia = null, noSsr } = (0, _system.getThemeProps)({ name: 'MuiUseMediaQuery', props: options, theme }); if (process.env.NODE_ENV !== 'production') { if (typeof queryInput === 'function' && theme === null) { console.error(['MUI: 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')); } } let query = typeof queryInput === 'function' ? queryInput(theme) : queryInput; query = query.replace(/^@media( ?)/m, ''); // TODO: Drop `useMediaQueryOld` and use `use-sync-external-store` shim in `useMediaQueryNew` once the package is stable const useMediaQueryImplementation = maybeReactUseSyncExternalStore !== undefined ? useMediaQueryNew : useMediaQueryOld; const match = useMediaQueryImplementation(query, defaultMatches, matchMedia, ssrMatchMedia, noSsr); if (process.env.NODE_ENV !== 'production') { // eslint-disable-next-line react-hooks/rules-of-hooks React.useDebugValue({ query, match }); } return match; }