Files
klz-cables.com/.pnpm-store/v10/files/78/c0a3cdb5b1a8eac0ccf0313c02edcbe5fa658f070675bc52fd8da6f4a021040866e396bf27f08901fabed46781bb95d7c3ded2f0e3967b4a77426651dcd376
Marc Mintel 5397309103
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
fix(products): fix breadcrumbs and product filtering (backport from main)
2026-02-24 16:04:21 +01:00

89 lines
3.7 KiB
Plaintext

'use client';
import React, { useCallback, useEffect, useReducer, useRef } from 'react';
import { WindowInfoContext } from '../WindowInfoProvider/context.js';
const reducer = (state, action) => {
const { payload: { breakpoints, animationRef, } } = action;
animationRef.current = null;
const { eventsFired: prevEventsFired, } = state;
const { documentElement: { style, clientWidth, clientHeight, }, } = document;
const { innerWidth: windowWidth, innerHeight: windowHeight, } = window;
const viewportWidth = `${clientWidth / 100}px`;
const viewportHeight = `${clientHeight / 100}px`;
const watchedBreakpoints = breakpoints ? Object.keys(breakpoints).reduce((matchMediaBreakpoints, key) => (Object.assign(Object.assign({}, matchMediaBreakpoints), { [key]: window.matchMedia(breakpoints[key]).matches })), {}) : {};
const newState = {
width: windowWidth,
height: windowHeight,
'--vw': viewportWidth,
'--vh': viewportHeight,
breakpoints: watchedBreakpoints,
eventsFired: prevEventsFired + 1,
};
// This method is a cross-browser patch to achieve above-the-fold, fullscreen mobile experiences.
// The technique accounts for the collapsing bottom toolbar of some mobile browsers which are out of normal flow.
// It provides an alternate to the "vw" and "vh" CSS units by generating respective CSS variables.
// It specifically reads the size of documentElement since its height does not include the toolbar.
style.setProperty('--vw', viewportWidth);
style.setProperty('--vh', viewportHeight);
return newState;
};
export const WindowInfoProvider = (props) => {
const { breakpoints, children, } = props;
const animationRef = useRef(null);
const [state, dispatch] = useReducer(reducer, {
width: undefined,
height: undefined,
'--vw': '',
'--vh': '',
breakpoints: {},
eventsFired: 0,
});
const requestAnimation = useCallback(() => {
if (animationRef.current)
cancelAnimationFrame(animationRef.current);
animationRef.current = requestAnimationFrame(() => dispatch({
type: 'UPDATE',
payload: {
breakpoints,
animationRef,
}
}));
}, [breakpoints]);
const requestThrottledAnimation = useCallback(() => {
setTimeout(() => {
requestAnimation();
}, 500);
}, [requestAnimation]);
useEffect(() => {
window.addEventListener('resize', requestAnimation);
window.addEventListener('orientationchange', requestThrottledAnimation);
return () => {
window.removeEventListener('resize', requestAnimation);
window.removeEventListener('orientationchange', requestThrottledAnimation);
};
}, [
requestAnimation,
requestThrottledAnimation,
]);
// use this effect to test rAF debounce by requesting animation every 1ms, for a total 120ms
// results: ~23 requests will be cancelled, ~17 requests will be cancelled, and only ~8 will truly dispatch
// useEffect(() => {
// const firstID = setInterval(requestAnimation, 1);
// setInterval(() => clearInterval(firstID), 120);
// }, [requestAnimation]);
useEffect(() => {
if (state.eventsFired === 0) {
dispatch({
type: 'UPDATE',
payload: {
breakpoints,
animationRef,
}
});
}
}, [
breakpoints,
state,
]);
return (React.createElement(WindowInfoContext.Provider, { value: Object.assign({}, state) }, children && children));
};
//# sourceMappingURL=index.js.map