@kadconsulting/dry
Version:
KAD Reusable Component Library
55 lines • 2.6 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { useMemo, useState, createContext, useLayoutEffect, } from 'react';
import { ViewportSizes } from '../../types';
import { DEFAULT_BREAKPOINTS } from './config';
import { rawNumericCSSValueFrom } from '../../internal/utilities/rawNumericCSSValueFrom';
export const ViewportBreakpointContext = createContext(undefined);
export const ViewportBreakpointProvider = ({ 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(ViewportSizes.Desktop);
case windowSize('width') >= numericBreakpoints.mobileMax:
return setLayout(ViewportSizes.Tablet);
default:
return setLayout(ViewportSizes.Mobile);
}
};
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, [numericBreakpoints, windowSize]);
const contextValue = useMemo(() => ({
layout,
windowInnerWidth,
windowInnerHeight,
}), [layout, windowInnerWidth, windowInnerHeight]);
return (_jsx(ViewportBreakpointContext.Provider, { value: contextValue, children: children }));
};
//# sourceMappingURL=ViewportBreakpointProvider.js.map