Table of Contents

Sticky sidebar navigation for long-form pages (case studies). Tracks the section currently in view via IntersectionObserver scroll-spy and highlights it with the accent rail.

Default

On the case study template this sits in a sticky aside (sticky top-24, hidden below lg). The active entry gets the accent color and a 2px accent rail. In this isolated preview no matching section ids exist on the page, so no entry is highlighted until one scrolls into view.

tsx
<TableOfContents
  items={[
    { id: 'problem-space', label: 'Problem space' },
    { id: 'my-role-design-process', label: 'My role & design process' },
    { id: 'outcomes-results', label: 'Outcomes & results' },
  ]}
/>

Custom label

tsx
<TableOfContents label="On this page" items={items} />

Props

PropTypeDefaultDescription
items*{ id: string; label: string }[]-Section anchors to list, in document order. Each id must match a section element id on the page.
labelstring"Contents"Uppercase eyebrow label above the list
classNamestring-Additional classes for the nav element

Import

tsx
import { TableOfContents } from '@/components/ui/TableOfContents'