UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

81 lines (80 loc) 3.16 kB
import * as React from 'react'; import { useLayoutEffect } from "../../../hooks/index.js"; export const mockMediaQueryList = { media: '', matches: false, onchange: () => { }, addListener: () => { }, removeListener: () => { }, addEventListener: () => { }, removeEventListener: () => { }, dispatchEvent: (_) => true, }; export const makeCurrentActiveMediaExpressions = (mediaToValue) => ({ xs: `(max-width: ${mediaToValue.s - 1}px)`, s: `(min-width: ${mediaToValue.s}px) and (max-width: ${mediaToValue.m - 1}px)`, m: `(min-width: ${mediaToValue.m}px) and (max-width: ${mediaToValue.l - 1}px)`, l: `(min-width: ${mediaToValue.l}px) and (max-width: ${mediaToValue.xl - 1}px)`, xl: `(min-width: ${mediaToValue.xl}px) and (max-width: ${mediaToValue.xxl - 1}px)`, xxl: `(min-width: ${mediaToValue.xxl}px) and (max-width: ${mediaToValue.xxxl - 1}px)`, xxxl: `(min-width: ${mediaToValue.xxxl}px)`, }); const safeMatchMedia = (query) => { if (typeof window === 'undefined' || typeof window.matchMedia !== 'function') { return mockMediaQueryList; } return window.matchMedia(query); }; class Queries { fix; queryListsDecl = []; constructor(breakpointsMap, fixBreakpoints) { const mediaToExpressionMap = makeCurrentActiveMediaExpressions(breakpointsMap); this.fix = fixBreakpoints; this.queryListsDecl = [ // order important here ['xs', safeMatchMedia(mediaToExpressionMap.xs)], ['s', safeMatchMedia(mediaToExpressionMap.s)], ['m', safeMatchMedia(mediaToExpressionMap.m)], ['l', safeMatchMedia(mediaToExpressionMap.l)], ['xl', safeMatchMedia(mediaToExpressionMap.xl)], ['xxl', safeMatchMedia(mediaToExpressionMap.xxl)], ['xxxl', safeMatchMedia(mediaToExpressionMap.xxxl)], ]; } getCurrentActiveMedia() { const activeMedia = this.queryListsDecl.find(([_, queryList]) => queryList.matches)?.[0]; if (!activeMedia) { return this.fix ? 'xs' : 's'; } else if (activeMedia === 'xs' && !this.fix) { return 's'; } return activeMedia; } addListeners(fn) { this.queryListsDecl.forEach(([_, queryList]) => queryList.addEventListener('change', fn)); } removeListeners(fn) { this.queryListsDecl.forEach(([_, queryList]) => queryList.removeEventListener('change', fn)); } } /** * @private */ export const useCurrentActiveMediaQuery = (breakpointsMap, fixBreakpoints, initialMediaQuery) => { const [state, _setState] = React.useState(initialMediaQuery ?? (fixBreakpoints ? 'xs' : 's')); useLayoutEffect(() => { const queries = new Queries(breakpointsMap, fixBreakpoints); const setState = () => { _setState(queries.getCurrentActiveMedia()); }; queries.addListeners(setState); setState(); return () => { queries.removeListeners(setState); }; }, [breakpointsMap, fixBreakpoints]); return state; }; //# sourceMappingURL=useCurrentActiveMediaQuery.js.map