Table of Contents
A scroll-tracking table of contents with active heading highlight.
Installation
Add the table of contents component with the shadcn CLI.
npx shadcn@latest add https://yami.ui.unsanity.ai/r/toc.jsonUsage
import { SimpleToc, useToc } from "@/components/ui/toc"
const items = [
{ id: "getting-started", label: "Getting Started", depth: 1 },
{ id: "installation", label: "Installation", depth: 2 },
{ id: "usage", label: "Usage", depth: 1 },
]
function MyPage() {
const activeId = useToc(items.map((i) => i.id))
return <SimpleToc items={items} activeId={activeId} />
}Examples
Static preview
Simulated active state — on a real page use useToc()Code
import { SimpleToc, useToc } from "@/components/ui/toc"
const items = [
{ id: "getting-started", label: "Getting Started", depth: 1 },
{ id: "installation", label: "Installation", depth: 2 },
{ id: "configuration", label: "Configuration", depth: 2 },
{ id: "usage", label: "Usage", depth: 1 },
{ id: "examples", label: "Examples", depth: 2 },
{ id: "api-reference", label: "API Reference", depth: 1 },
]
function DocPage() {
const activeId = useToc(items.map((i) => i.id))
return (
<aside>
<SimpleToc items={items} activeId={activeId} />
</aside>
)
}Custom composition
Manual layout with Toc + TocList + TocItem + TocLinkCode
import { Toc, TocList, TocItem, TocLink, useToc } from "@/components/ui/toc"
function DocPage() {
const activeId = useToc(["getting-started", "installation", "configuration", "usage"])
return (
<Toc activeId={activeId}>
<p className="mb-2 text-xs font-semibold uppercase tracking-wider text-muted-foreground">
On this page
</p>
<TocList>
<TocItem depth={1}><TocLink itemId="getting-started">Getting Started</TocLink></TocItem>
<TocItem depth={2}><TocLink itemId="installation">Installation</TocLink></TocItem>
<TocItem depth={2}><TocLink itemId="configuration">Configuration</TocLink></TocItem>
<TocItem depth={1}><TocLink itemId="usage">Usage</TocLink></TocItem>
</TocList>
</Toc>
)
}