{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "table-of-contents",
  "type": "registry:component",
  "title": "Table Of Contents",
  "description": "Auto-generated table of contents from page headings.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/table-of-contents/table-of-contents.tsx",
      "content": "\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\n\ntype TableOfContentsProps = {\n  sections: { id: string; title: string }[];\n};\n\nfunction handleClick(id: string) {\n  const element = document.querySelector(`#${id}`);\n  if (element) {\n    element.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n  }\n}\n\nfunction useActiveSection(sections: { id: string; title: string }[]) {\n  const [activeSection, setActiveSection] = useState<null | string>(null);\n\n  useEffect(() => {\n    const observer = new IntersectionObserver(\n      (entries) => {\n        entries.forEach((entry) => {\n          if (entry.isIntersecting) {\n            setActiveSection(entry.target.id);\n          }\n        });\n      },\n      {\n        rootMargin: \"-100px 0px -66% 0px\",\n        threshold: 0,\n      },\n    );\n\n    sections.forEach((section) => {\n      const element = document.querySelector(`#${section.id}`);\n      if (element) {\n        observer.observe(element);\n      }\n    });\n\n    return () => {\n      sections.forEach((section) => {\n        const element = document.querySelector(`#${section.id}`);\n        if (element) {\n          observer.unobserve(element);\n        }\n      });\n    };\n  }, [sections]);\n\n  return activeSection;\n}\n\nexport function TableOfContents({ sections }: TableOfContentsProps) {\n  const activeSection = useActiveSection(sections);\n\n  if (sections.length === 0) {\n    return null;\n  }\n\n  return (\n    <aside className=\"hidden xl:block\">\n      <div className=\"sticky top-8\">\n        <div className=\"border-l-2 border-border pl-4\">\n          <h3 className=\"text-sm font-semibold mb-4 text-muted-foreground uppercase tracking-wider\">\n            On This Page\n          </h3>\n          <nav className=\"space-y-2\">\n            {sections.map((section) => (\n              <button\n                className={cn(\n                  \"block text-left text-sm transition-colors\",\n                  \"hover:text-foreground\",\n                  activeSection === section.id\n                    ? \"text-foreground font-medium\"\n                    : \"text-muted-foreground\",\n                )}\n                key={section.id}\n                onClick={() => {\n                  handleClick(section.id);\n                }}\n                type=\"button\"\n              >\n                {section.title}\n              </button>\n            ))}\n          </nav>\n        </div>\n      </div>\n    </aside>\n  );\n}\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
