Table of contents

TableOfContents is the course outline beside a lesson: the course title, its sections and links to the study tools. Use it next to a lesson so the learner can see where they are and jump around.

  • Beta
  • Accessibility
  • Figma Table of Content 292:59319 (3842:31957)
  • packages/ui/src/components/TableOfContents

Beta until design confirms the collapsed button and the section-being-written state, which Figma does not draw (C94).

Preview

The expanded outline with the second section open, and the collapsed button. Every prop is listed in the API reference below.

Installation

Availability

@nuton/ui and @nuton/tokens are private workspace packages and aren't published yet (D4, D12). Inside the Nuton monorepo, add them as workspace dependencies.

bash
pnpm add @nuton/ui @nuton/tokens @remixicon/react
tsx
import '@nuton/tokens/tokens.css'
import '@nuton/ui/styles.css'

Usage

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

const sections = [
  { id: 'a', label: 'Introduction to Design Principles' },
  { id: 'b', label: 'Form and Function in Design' },
]

<TableOfContents
  title="The Design of Everyday Things"
  items={sections}
  activeId={current}
  onSelect={setCurrent}
/>
  • Put it in a column beside the lesson, 248px wide, and keep it in view while the lesson scrolls.
  • Pass the section being read as activeId: it is marked aria-current and set on a grey band.
  • Use extras for the study tools (Study Guide, Flash Cards, Final Exam). They sit under a second divider.
  • Give a section that is still being written status: 'generating': it shows a spinner and cannot be opened yet.
  • Long section titles are cut with an ellipsis; keep the full title in the lesson heading.

Variants and sizes

One size. It is a fixed 248px card, and collapses to a 60px square.

Sizes

Expanded: 248 wide, 12px padding, radius 20, section rows 40 tall and 7px apart. Collapsed: a 60px square holding one 36px round button.

States and interactions

Current sectionBg/Soft-200 band and aria-current.
Being writtenSpinner and a hidden “still being written”. Live only; Figma does not draw it (C94).
CollapsedOne round button. Live only; Figma does not draw it (C94).

Composition examples

Beside a lesson, under the TabStrip of courses, with the AI Tutor ChatPanel on the other side. See Learner → Lesson in the product review.

API reference

Props

Table of contents props
PropTypeDefaultDescription
titleReactNode—The course title. Fraunces 20/28.
titleAs'p' | 'h2' | 'h3''p'Element for the title. The page's own heading is the lesson title, so the default is a paragraph.
itemsTableOfContentsItem[]—The sections: { id, label, icon?, status? }.
activeIdstring—The section being read. Marked aria-current.
onSelect(id: string) => void—Called when a section is chosen.
extrasTableOfContentsItem[]—Links under the divider, such as Study Guide, Flash Cards and Final Exam.
onExtraSelect(id: string) => void—Called when an extra link is chosen.
collapsedboolean—Collapsed to one round button (controlled).
defaultCollapsedbooleanfalseInitial state when uncontrolled.
onCollapsedChange(collapsed: boolean) => void—Called when the button collapses or expands it.
labelsPartial<TableOfContentsLabels>—Strings: nav, collapse, expand, generating.

Accessibility

Keyboard

KeyBehaviour
TabMoves to the collapse button, then through the sections and links in order.
Enter / SpaceOpens the focused section, or collapses and expands the outline.

Screen readers

A navigation landmark named “Table of contents”. The open section is announced as current; a section still being written is read as “still being written” and cannot be opened.

Focus

Every row shows the focus ring. The collapse button swaps for the expand button in the same place.

Contrast and colour

Strong-950 text on white and on the Soft-200 band is above 4.5:1. The current section is marked by the band and by aria-current, not by colour alone.

Touch and pointer

Rows are 40px tall and the collapse button is 36px.

You must: keep the section titles unique and put the full course title in the page, because long titles are cut with an ellipsis.

Figma mapping

Table of Content 292:59319, used in the lesson frames (3842:31957). Sections are Dropdown Items [1.1]; the collapse button is a 36px lighter button with collapse-diagonal-2-line.

Guidelines and related components

Use Table of contents for

  • The outline beside a lesson or a course page
  • Jumping between the sections of one course

Don't use Table of contents for

  • Site navigation (use the Sidebar)
  • Switching between courses (use the Tab strip)

Do and don't

DoMark one section as current The learner always knows where they are.
Don'tLeave every section the same Nothing shows which one is open.