ifixkart-storefront/components/StickyHeaderSpacer.tsx

47 lines
1.5 KiB
TypeScript

'use client';
import { useEffect, useLayoutEffect, useState } from 'react';
import { STOREFRONT_STICKY_SCROLL_Y } from '@/layout/Header';
/**
* Reserves vertical space when Header (+ Navbar on xl) become fixed on scroll,
* so page content does not jump underneath.
*/
export function StickyHeaderSpacer() {
const [height, setHeight] = useState(0);
const [isFixed, setIsFixed] = useState(false);
useEffect(() => {
const onScroll = () => {
setIsFixed(window.scrollY > STOREFRONT_STICKY_SCROLL_Y);
};
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
useLayoutEffect(() => {
const measure = () => {
if (!isFixed) {
setHeight(0);
return;
}
const header = document.querySelector<HTMLElement>(
'[data-storefront-header]'
);
const nav = document.querySelector<HTMLElement>('[data-storefront-nav]');
const headerH = header?.offsetHeight || 0;
const navVisible =
!!nav && window.getComputedStyle(nav).display !== 'none';
const navH = navVisible ? nav.offsetHeight || 0 : 0;
setHeight(headerH + navH);
};
measure();
window.addEventListener('resize', measure, { passive: true });
return () => window.removeEventListener('resize', measure);
}, [isFixed]);
if (!isFixed || height <= 0) return null;
return <div style={{ height }} aria-hidden="true" />;
}