import { useEffect, useRef, useState } from 'react'; import styles from './SectionNav.module.css'; export default function SectionNav({ sections }) { const [active, setActive] = useState(sections[0]?.id ?? ''); const navRef = useRef(null); const isClickScrolling = useRef(false); const clickTimeout = useRef(null); useEffect(() => { const els = sections .map((s) => document.getElementById(s.id)) .filter(Boolean); if (els.length === 0) return undefined; const ratios = new Map(); const observer = new IntersectionObserver( (entries) => { if (isClickScrolling.current) return; for (const entry of entries) { ratios.set(entry.target.id, entry.intersectionRatio); } let best = ''; let bestRatio = -1; for (const [id, ratio] of ratios) { if (ratio > bestRatio) { best = id; bestRatio = ratio; } } if (best && bestRatio > 0) setActive(best); }, { threshold: [0, 0.1, 0.25, 0.5, 0.75, 1] } ); for (const el of els) observer.observe(el); return () => observer.disconnect(); }, [sections]); useEffect(() => () => clearTimeout(clickTimeout.current), []); const handleClick = (id) => { const el = document.getElementById(id); if (!el) return; setActive(id); isClickScrolling.current = true; const nav = navRef.current; const stickyBottom = nav ? nav.getBoundingClientRect().bottom : 0; const top = el.getBoundingClientRect().top + window.scrollY - stickyBottom - 8; window.scrollTo({ top, behavior: 'smooth' }); clearTimeout(clickTimeout.current); clickTimeout.current = setTimeout(() => { isClickScrolling.current = false; }, 800); }; return ( ); }