'use client'; import { useEffect, useState } from 'react'; import { cn } from '$shared/lib'; import type { NavItem } from '../model/types'; interface Props { /** * Navigation items to render */ items: NavItem[]; } /** * Fixed sidebar navigation, visible on lg+ screens. */ export function SidebarNav({ items }: Props) { const [activeSection, setActiveSection] = useState('bio'); useEffect(() => { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { setActiveSection(entry.target.id); } }); }, { rootMargin: '-20% 0px -70% 0px', threshold: 0 }, ); items.forEach((item) => { const el = document.getElementById(item.id); if (el) { observer.observe(el); } }); return () => observer.disconnect(); }, [items]); /** * Scrolls to the section by id with a 40px offset. */ function scrollToSection(id: string) { const el = document.getElementById(id); if (el) { const top = el.getBoundingClientRect().top + window.scrollY - 40; window.scrollTo({ top, behavior: 'smooth' }); } } return ( ); }