"use client" import React, { useEffect, useState, useCallback, useRef } from 'react' import { cn } from '../../utils' import { scrollElementIntoView } from '../../utils/scroll-into-view' export interface StickyNavSection { id: string label: string } interface StickySectionNavProps { sections: StickyNavSection[] activeSection: string onSectionClick: (sectionId: string) => void className?: string ribbonPosition?: 'left' | 'right' ribbonColor?: string } /** * Reusable sticky navigation component for section-based navigation * Used in vendor detail pages, knowledge base, documentation, etc. */ export function StickySectionNav({ sections, activeSection, onSectionClick, className, ribbonPosition = 'left', ribbonColor = 'var(--color-accent-primary)' }: StickySectionNavProps) { const navHeight = sections.length * 40 // 40px per item (h-10) return ( ) } /** * SIMPLEST POSSIBLE IMPLEMENTATION - Just make it work */ export function useSectionNavigation( sections: { id: string; ref: React.RefObject }[], options?: { offset?: number } ) { const [activeSection, setActiveSection] = useState(sections[0]?.id || '') const isScrollingFromClick = useRef(false) const { offset = 100 } = options || {} // Handle click - scroll to the element via the canonical helper. // The `offset` prop maps to `headerOffset` (sticky chrome above the // section nav); same smooth-scroll mechanics every other anchor // surface in the app uses. const handleSectionClick = useCallback((sectionId: string) => { const targetElement = document.getElementById(sectionId) if (!targetElement) return // Prevent scroll spy while we're scrolling isScrollingFromClick.current = true setActiveSection(sectionId) scrollElementIntoView(targetElement, { headerOffset: offset }) // Allow scroll spy again after scroll completes setTimeout(() => { isScrollingFromClick.current = false }, 500) }, [offset]) // Make sure elements have IDs useEffect(() => { sections.forEach(section => { if (section.ref.current && !section.ref.current.id) { section.ref.current.id = section.id } }) }, [sections]) // Simple scroll spy useEffect(() => { const handleScroll = () => { if (isScrollingFromClick.current) return const scrollPosition = window.scrollY + offset + 50 // Find which section we're in let currentSection = sections[0]?.id || '' for (let i = sections.length - 1; i >= 0; i--) { const element = document.getElementById(sections[i].id) if (element && scrollPosition >= element.offsetTop) { currentSection = sections[i].id break } } setActiveSection(currentSection) } // Throttle the scroll handler let scrollTimer: NodeJS.Timeout const throttledScroll = () => { clearTimeout(scrollTimer) scrollTimer = setTimeout(handleScroll, 100) } window.addEventListener('scroll', throttledScroll) handleScroll() // Check initial position return () => { window.removeEventListener('scroll', throttledScroll) clearTimeout(scrollTimer) } }, [sections, offset]) return { activeSection, handleSectionClick } }