"use client" import * as React from "react" import { IconMenu3 } from "@tabler/icons-react" import { cn } from "@/lib/utils" import { Button } from "@/registry/new-york-v4/ui/button" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/registry/new-york-v4/ui/dropdown-menu" function useActiveItem(itemIds: string[]) { const [activeId, setActiveId] = React.useState(null) React.useEffect(() => { const observer = new IntersectionObserver( (entries) => { for (const entry of entries) { if (entry.isIntersecting) { setActiveId(entry.target.id) } } }, { rootMargin: "0% 0% -80% 0%" } ) for (const id of itemIds ?? []) { const element = document.getElementById(id) if (element) { observer.observe(element) } } return () => { for (const id of itemIds ?? []) { const element = document.getElementById(id) if (element) { observer.unobserve(element) } } } }, [itemIds]) return activeId } export function DocsTableOfContents({ toc, variant = "list", className, }: { toc: { title?: React.ReactNode url: string depth: number }[] variant?: "dropdown" | "list" className?: string }) { const [open, setOpen] = React.useState(false) const itemIds = React.useMemo( () => toc.map((item) => item.url.replace("#", "")), [toc] ) const activeHeading = useActiveItem(itemIds) if (!toc?.length) { return null } if (variant === "dropdown") { return ( {toc.map((item) => ( { setOpen(false) }} data-depth={item.depth} className="data-[depth=3]:pl-6 data-[depth=4]:pl-8" > {item.title} ))} ) } return (

On This Page

{toc.map((item) => ( {item.title} ))}
) }