Table of Contents
Preview: Line
"On this page" list with scroll-spy: highlights the heading currently in view.
Import
import { TableOfContents } from '@marbleui/ui'Props
<TableOfContents>
| Prop | Type | Default | Description |
|---|---|---|---|
| items *required | TocItem[] | — | |
| className | string | — | |
| root | Element | null | null | Scroll container to observe (defaults to the viewport). |
| title | string | 'On this page' | |
| variant | 'plain' | 'line' | 'line' |
Usage notes
“On this page” list that highlights the heading currently in view. Use on long documents; for step progress use Stepper.
<TableOfContents
items={[
{ id: 'install', title: 'Installation' },
{ id: 'usage', title: 'Usage' },
{ id: 'props', title: 'Props', level: 3 },
]}
/>
- Each
idmust match an elementidin the page; missing ones are skipped by the scroll-spy. levelis2(default) or3for indentation.variantisline(default) orplain.- If the content scrolls in its own container rather than the window, pass that element as
root. title(default “On this page”) is both the visible heading and the nav’saria-label. Links are plain#idanchors.
Example source · show· hide
import { useState } from 'react'
import { TableOfContents } from './table-of-contents'
const items = [
{ id: 'toc-intro', title: 'Introduction' },
{ id: 'toc-install', title: 'Installation' },
{ id: 'toc-npm', title: 'With npm', level: 3 as const },
{ id: 'toc-registry', title: 'With the registry', level: 3 as const },
{ id: 'toc-usage', title: 'Usage' },
{ id: 'toc-faq', title: 'FAQ' },
]
function Demo({ variant }: { variant: 'line' | 'plain' }) {
const [root, setRoot] = useState<HTMLDivElement | null>(null)
return (
<div className="flex w-[36rem] gap-6">
<div ref={setRoot} tabIndex={0} role="region" aria-label="Scrollable example" className="h-64 flex-1 overflow-y-auto outline-none focus-visible:ring-2 focus-visible:ring-ring rounded-lg border border-border bg-surface p-4 text-sm text-fg-muted">
{items.map((i) => (
<section key={i.id} className="mb-6">
<h3 id={i.id} className={i.level === 3 ? 'font-medium text-fg' : 'text-base font-semibold text-fg'}>{i.title}</h3>
<p className="mt-2">Scroll this panel: the list on the right follows along. Section text for “{i.title}”.</p>
<p className="mt-2">More content so each section takes up some space in the scroll container.</p>
</section>
))}
</div>
{root && <TableOfContents items={items} variant={variant} root={root} className="w-44" />}
</div>
)
}
export const styles = { Line: () => <Demo variant="line" />, Plain: () => <Demo variant="plain" /> }Source: packages/ui/src/table-of-contents/table-of-contents.tsx
Catalog
- Category
- navigation
- Priority
- Core
- Primitive
- composed
- React Aria
- Link