@razorpay/blade
Version:
The Design System that powers Razorpay
136 lines (131 loc) • 6.3 kB
JavaScript
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