UNPKG

@razorpay/blade

Version:

The Design System that powers Razorpay

136 lines (131 loc) 6.3 kB
import _slicedToArray from '@babel/runtime/helpers/slicedToArray'; import { useMemo, useCallback, useState } from 'react'; import '../getPlatformType/index.js'; import '../getMediaQuery/index.js'; import { useIsomorphicLayoutEffect } from '../useIsomorphicLayoutEffect.js'; import { getMediaQuery } from '../getMediaQuery/getMediaQuery.js'; import { getPlatformType } from '../getPlatformType/getPlatformType.js'; var deviceType = { desktop: 'desktop', mobile: 'mobile' }; var useBreakpoint = function useBreakpoint(_ref) { var _window; var breakpoints = _ref.breakpoints; var supportsMatchMedia = typeof document !== 'undefined' && typeof window !== 'undefined' && typeof ((_window = window) === null || _window === void 0 ? void 0 : _window.matchMedia) === 'function'; var breakpointsTokenAndQueryCollection = useMemo(function () { return supportsMatchMedia ? Object.entries(breakpoints).map(function (_ref2, index, breakpointsArray) { var _breakpointsArray; var _ref3 = _slicedToArray(_ref2, 2), token = _ref3[0], screenSize = _ref3[1]; var min = screenSize; var maxValue = (_breakpointsArray = breakpointsArray[index + 1]) === null || _breakpointsArray === void 0 ? void 0 : _breakpointsArray[1]; var mediaQuery = getMediaQuery({ min: min, max: maxValue ? maxValue - 1 : undefined }); return { token: token, screenSize: screenSize, mediaQuery: mediaQuery }; }) : []; }, [breakpoints, supportsMatchMedia]); var getMatchedDeviceType = useCallback(function (matchedBreakpoint) { var matchedDeviceType = deviceType.mobile; var platform = getPlatformType(); if (platform === 'react-native') { matchedDeviceType = deviceType.mobile; } else if (platform === 'browser') { if (matchedBreakpoint && ['base', 'xs', 's'].includes(matchedBreakpoint)) { // tablet is also categorised as mobile matchedDeviceType = deviceType.mobile; } else { matchedDeviceType = deviceType.desktop; } } else if (platform === 'node') { //@TODO: Check for useragent for node matchedDeviceType = deviceType.desktop; } return matchedDeviceType; }, []); var getMatchedBreakpoint = useCallback(function (event) { var _breakpointsTokenAndQ, _breakpointsTokenAndQ2; var matchedBreakpoint = (_breakpointsTokenAndQ = (_breakpointsTokenAndQ2 = breakpointsTokenAndQueryCollection.find(function (_ref4) { var _ref4$mediaQuery = _ref4.mediaQuery, mediaQuery = _ref4$mediaQuery === void 0 ? '' : _ref4$mediaQuery; // this will run whenever mediaQuery change event is triggered if ((event === null || event === void 0 ? void 0 : event.media) === mediaQuery) { return true; } // this will run when the state is initialised for the first time and hence the event object will be empty because the event listener wouldn't have triggered if (window.matchMedia(mediaQuery).matches) { return true; } return false; })) === null || _breakpointsTokenAndQ2 === void 0 ? void 0 : _breakpointsTokenAndQ2.token) !== null && _breakpointsTokenAndQ !== void 0 ? _breakpointsTokenAndQ : undefined; return matchedBreakpoint; }, [breakpointsTokenAndQueryCollection]); var _useState = useState({ matchedBreakpoint: undefined, matchedDeviceType: deviceType.desktop }), _useState2 = _slicedToArray(_useState, 2), breakpointAndDevice = _useState2[0], setBreakpointAndDevice = _useState2[1]; useIsomorphicLayoutEffect(function () { // set the breakpoint and devicetype for the first time because eventlisteners will only trigger after the screen is actually changed setBreakpointAndDevice(function () { var matchedBreakpoint = getMatchedBreakpoint(); var matchedDeviceType = getMatchedDeviceType(matchedBreakpoint); return { matchedBreakpoint: matchedBreakpoint, matchedDeviceType: matchedDeviceType }; }); // for react-native and SSR we don't need to register event listeners if (!supportsMatchMedia) { return undefined; } var handleMediaQueryChange = function handleMediaQueryChange(event) { setBreakpointAndDevice(function () { var matchedBreakpoint = getMatchedBreakpoint(event); var matchedDeviceType = getMatchedDeviceType(matchedBreakpoint); return { matchedBreakpoint: matchedBreakpoint, matchedDeviceType: matchedDeviceType }; }); }; var mediaQueryInstances = breakpointsTokenAndQueryCollection.map(function (_ref5) { var _ref5$mediaQuery = _ref5.mediaQuery, mediaQuery = _ref5$mediaQuery === void 0 ? '' : _ref5$mediaQuery; var mediaQueryInstance = window.matchMedia(mediaQuery); /** * the mediaquery event listener is available on mediaQuery instances and not `window` * we iterate over all the breakpoints we have, register each instance and store them as `mediaQueryInstances` so we can later unregister all of them. */ if (mediaQueryInstance.addEventListener) { mediaQueryInstance.addEventListener('change', handleMediaQueryChange); } else { // In older browsers MediaQueryList do not yet inherit from EventTarget, So using addListener as fallback - https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener mediaQueryInstance.addListener(handleMediaQueryChange); } return mediaQueryInstance; }); return function () { mediaQueryInstances.forEach(function (mediaQueryInstance) { if (mediaQueryInstance.removeEventListener) { mediaQueryInstance.removeEventListener('change', handleMediaQueryChange); } else { // In older browsers MediaQueryList do not yet inherit from EventTarget, So using removeListener as fallback - https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/removeListener mediaQueryInstance.removeListener(handleMediaQueryChange); } }); }; }, [breakpointsTokenAndQueryCollection, getMatchedBreakpoint, getMatchedDeviceType, supportsMatchMedia]); return breakpointAndDevice; }; export { useBreakpoint }; //# sourceMappingURL=useBreakpoint.js.map