Skip to content

TOC

Table of contents primitives for rendering section links with depth indentation and active states.

Preview

Installation

$pnpm exec dgadd add ui/toc
[Installs to]src/components/ui/toc[Item]ui/toc

dgadd is not public on npm yet. Until the first release, pack @diffgazer/add from the repository and install that tarball into this app, which is what puts dgadd on pnpm exec.

UI components require Tailwind CSS v4. Local copy mode imports src/styles/styles.css; package mode uses @diffgazer/ui CSS once packages are available.

Usage

tsx
import { Toc, TocItem, TocList } from "@/components/ui/toc";const items = [  { title: "Overview", href: "#overview", depth: 2, active: false },  { title: "Installation", href: "#installation", depth: 2, active: true },  { title: "Configuration", href: "#configuration", depth: 2, active: false },];export default function TocDefault() {  return (    <Toc title="On this page" className="w-full max-w-xs">      <TocList>        {items.map((item) => (          <TocItem key={item.href} href={item.href} depth={item.depth} active={item.active}>            {item.title}          </TocItem>        ))}      </TocList>    </Toc>  );}

Examples

Nested Depth (h2/h3/h4) + Active State

Preview

Active Heading Tracking (scroll container)

Preview

API Reference

Toc

NameTypeDefaultDescription
titlestring"On this page"Heading text and accessible label for the nav landmark.
as"h2" | "h3" | "h4""h2"Heading level used for the title.
childrenReactNodeTypically a TocList with TocItem children.

TocList

NameTypeDefaultDescription
childrenReactNodeTocItem children rendered inside a <ul>.

TocItem

NameTypeDefaultDescription
depthnumber2Heading depth (2 = h2). Drives left padding; values below 2 are treated as 2.
activebooleanfalseMarks the link as the current location. Adds aria-current="location" and data-selected.
hrefstringAnchor href. Omit when rendering via the render-prop form.
childrenrequiredReactNode | (props: TocItemRenderProps) => ReactNodeLink label, or a render function for framework Link integration.

Accessibility

Notes

Current-location mark

The library spells "you are here" one way: a 2px left rail in --primary (registry/lib/marker-rail.ts). Full-bleed inversion is reserved for the TRANSIENT keyboard highlight; a row that is both the current location and the highlight keeps the inversion and flips its rail to --primary-foreground so the mark survives. The rail is reserved transparently in the resting state and pulled back by its own width, so a row's label never shifts horizontally when it becomes current — that anti-shift geometry is the contract, and it is why the rail costs 0px of label width at 375/390 where a full-bleed fill reads as a solid slab. Toc is the reference implementation of that rail.

Headless-friendly

Toc/TocList/TocItem are presentation primitives. Pair them with your own heading tracking logic (e.g. IntersectionObserver or Fumadocs AnchorProvider).

Depth

Use the depth prop on TocItem to indent nested headings consistently (h2/h3/h4).

Page Layout

Toc renders the nav landmark and its heading only. Width, sticky offset, and page padding are call-site decisions — pass them via className (the docs site uses w-56 shrink-0 py-8 pr-4).

Active Marker

An active TocItem bolds its label and paints a 2px rail segment over the TocList hairline, matching the sidebar bar/terminal marker language.

Source

Install via CLI: pnpm exec dgadd add ui/toc.

Highlighted source loads after this disclosure opens. Browse the source repository.