"use client"; import { usePathname } from "next/navigation"; import React, { createContext, useContext, useEffect, useRef, useState, } from "react"; interface HeaderContextType { dropdownContent: React.ReactNode; setDropdownContent: (content: React.ReactNode) => void; clearDropdown: (force?: boolean) => void; resetDropdownTimeout: () => void; dropdownKey: number; headerHeight: React.RefObject; headerTop: React.RefObject; } const HeaderContext = createContext(undefined); export const HeaderProvider = ({ children }: { children: React.ReactNode }) => { const [dropdownContent, setDropdownContent] = useState(null); const [dropdownKey, setDropdownKey] = useState(0); const headerHeight = useRef(0); const headerTop = useRef(0); const pathname = usePathname(); const timeout = useRef(null); const clearDropdown = (force?: boolean) => { if (force) { setDropdownContent(null); return; } if (timeout.current) { clearTimeout(timeout.current); } timeout.current = window.setTimeout(() => { setDropdownContent(null); }, 500); }; const resetDropdownTimeout = () => { if (timeout.current) { clearTimeout(timeout.current); } }; useEffect(() => { const header = document.querySelector(".header") as HTMLElement; if (header) { const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { headerHeight.current = entry.contentRect.height; } }); resizeObserver.observe(header); headerHeight.current = header.clientHeight; headerTop.current = header.getBoundingClientRect().top; const onScroll = () => { headerTop.current = header.getBoundingClientRect().top; }; window.addEventListener("scroll", onScroll, { passive: true }); return () => { resizeObserver.disconnect(); window.removeEventListener("scroll", onScroll); }; } }, [pathname]); return ( { resetDropdownTimeout(); if (content === dropdownContent) return; setDropdownKey((prev) => prev + 1); setDropdownContent(content); }, clearDropdown, resetDropdownTimeout, dropdownKey, headerHeight, headerTop, }} > {children} ); }; export const useHeaderContext = () => { const context = useContext(HeaderContext); if (!context) { throw new Error("useHeaderContext must be used within a HeaderProvider"); } return context; }; export const useHeaderHeight = () => { const [headerHeight, setHeaderHeight] = useState(0); useEffect(() => { const header = document.querySelector(".header"); if (header) { const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { setHeaderHeight(entry.contentRect.height); } }); resizeObserver.observe(header); setHeaderHeight(header.clientHeight); return () => { resizeObserver.disconnect(); }; } }, []); return { headerHeight }; };