"use client" import * as React from "react" import { Menu, Search } from "lucide-react" import { Link } from "@/i18n/routing" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { DOC_SECTION_IDS, type DocSectionId } from "@/lib/docs-sections" type DocsShellSection = { id: DocSectionId title: string } export function DocsShell({ mobileHeader, searchPlaceholder, sections, children, }: { mobileHeader: string searchPlaceholder: string sections: DocsShellSection[] children: React.ReactNode }) { const [searchQuery, setSearchQuery] = React.useState("") const [activeSection, setActiveSection] = React.useState("overview") const [isMobileMenuOpen, setIsMobileMenuOpen] = React.useState(false) const activeSectionRef = React.useRef("overview") React.useEffect(() => { activeSectionRef.current = activeSection }, [activeSection]) const filteredSections = React.useMemo(() => { const query = searchQuery.trim().toLowerCase() if (!query) return sections return sections.filter((section) => section.title.toLowerCase().includes(query)) }, [searchQuery, sections]) React.useEffect(() => { const sectionEls = DOC_SECTION_IDS.map((id) => document.getElementById(id)) let rafId: number | null = null const handleScroll = () => { if (rafId !== null) return rafId = window.requestAnimationFrame(() => { rafId = null const scrollPosition = window.scrollY + 100 let nextActive: DocSectionId | null = null for (let i = 0; i < sectionEls.length; i++) { const el = sectionEls[i] if (!el) continue if (el.offsetTop <= scrollPosition && el.offsetTop + el.offsetHeight > scrollPosition) { nextActive = el.id as DocSectionId break } } if (nextActive && nextActive !== activeSectionRef.current) { activeSectionRef.current = nextActive setActiveSection(nextActive) } }) } window.addEventListener("scroll", handleScroll, { passive: true }) handleScroll() return () => { window.removeEventListener("scroll", handleScroll) if (rafId !== null) window.cancelAnimationFrame(rafId) } }, []) const scrollToSection = (id: DocSectionId) => { const element = document.getElementById(id) if (!element) return window.scrollTo({ top: element.offsetTop - 80, behavior: "auto" }) activeSectionRef.current = id setActiveSection(id) setIsMobileMenuOpen(false) } return (
{mobileHeader}
{children}
) }