UNPKG

@kadconsulting/dry

Version:
54 lines 2.44 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { useMemo, useState, createContext, useLayoutEffect, } from 'react'; import { Layouts } from '../../types'; import { DEFAULT_BREAKPOINTS } from './config'; import { rawNumericCSSValueFrom } from '../../internal/utilities/rawNumericCSSValueFrom'; export const LayoutContext = createContext(undefined); export const LayoutProvider = ({ theme, children, }) => { const windowSize = (dimension) => { if (typeof window === 'undefined') return 0; if (window.visualViewport) return window.visualViewport[dimension] ?? 0; return window[dimension === 'width' ? 'innerWidth' : 'innerHeight'] ?? 0; }; const [layout, setLayout] = useState(null); const [windowInnerWidth, setWindowInnerWidth] = useState(windowSize('width')); const [windowInnerHeight, setWindowInnerHeight] = useState(windowSize('height')); const numericBreakpoints = useMemo(() => { /** Though not recommended, applications can opt out of the ThemeProvider */ if (!theme) return DEFAULT_BREAKPOINTS; /** Compute the breakpoints by reading from the CSS variables converted to JS by the ThemeProvider */ const { breakpoints } = theme; return Object.keys(breakpoints).reduce((acc, key) => { acc[key] = rawNumericCSSValueFrom(breakpoints[key]); return acc; }, {}); }, [theme]); useLayoutEffect(() => { const handleResize = () => { setWindowInnerWidth(windowSize('width')); setWindowInnerHeight(windowSize('height')); switch (true) { case windowSize('width') >= numericBreakpoints.tabletMax: return setLayout(Layouts.Desktop); case windowSize('width') >= numericBreakpoints.mobileMax: return setLayout(Layouts.Tablet); default: return setLayout(Layouts.Mobile); } }; handleResize(); window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, [numericBreakpoints, windowSize]); return (_jsx(LayoutContext.Provider, { value: { layout, windowInnerWidth, windowInnerHeight, }, children: children })); }; //# sourceMappingURL=LayoutProvider.js.map