@shopgate/engage
Version:
Shopgate's ENGAGE library.
66 lines (59 loc) • 2.19 kB
JavaScript
import "core-js/modules/es.string.replace.js";
import React, { createContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useTheme } from '@shopgate/engage/styles';
/**
* @typedef {import('..').Breakpoint} Breakpoint
*/
/** @type {import('react').Context<Breakpoint>} */
import { jsx as _jsx } from "react/jsx-runtime";
export const ActiveBreakpointContext = /*#__PURE__*/createContext(undefined);
/**
* @param {Object} props The component props
* @param {React.ReactNode} props.children The children to render within the provider
* @returns {JSX.Element} The ActiveBreakpointProvider component
*/
const ActiveBreakpointProvider = ({
children
}) => {
const theme = useTheme();
// ['xl', 'lg', ..., 'xs']
const breakpoints = [].concat(theme.breakpoints.keys).reverse();
/**
* Retrieve the initial breakpoint based on the current window size.
* @returns {Breakpoint|undefined} The initial breakpoint based on the current window size.
*/
const getInitialBreakpoint = () => {
if (typeof window === 'undefined') return undefined;
return breakpoints.find(bp => window.matchMedia(theme.breakpoints.up(bp).replace(/^@media( ?)/m, '')).matches);
};
/** @type {[Breakpoint, React.Dispatch<React.SetStateAction<Breakpoint>>]} */
const [active, setActive] = useState(getInitialBreakpoint);
useEffect(() => {
if (typeof window === 'undefined') return undefined;
const queries = breakpoints.map(bp => ({
bp,
mql: window.matchMedia(theme.breakpoints.up(bp).replace(/^@media( ?)/m, ''))
}));
/**
* Updates the active breakpoint based on the current media query matches.
*/
const update = () => {
const matched = queries.find(({
mql
}) => mql.matches);
setActive(matched?.bp);
};
queries.forEach(({
mql
}) => mql.addEventListener('change', update));
return () => queries.forEach(({
mql
}) => mql.removeEventListener('change', update));
}, [breakpoints, theme]);
return /*#__PURE__*/_jsx(ActiveBreakpointContext.Provider, {
value: active,
children: children
});
};
export default ActiveBreakpointProvider;