Knit UI
GitHub

Playground

Loading playground…

Playground
<TableOfContents
  data={[{ value: "Introduction", depth: 1 }, { value: "Getting Started", depth: 1 }, { value: "Installation", depth: 2 }, { value: "Configuration", depth: 2 }, { value: "Basic Usage", depth: 3 }, { value: "Advanced Topics", depth: 1 }, { value: "API Reference", depth: 2 }]}
  variant="light"
  size="md"
  defaultActive={0}
  depthOffset="$lg"
  minDepthToOffset={1}
/>

Examples

Variants

All three visual variants of the active-item highlight, side by side.

Loading example…

VariantsSourceStorybook

Sizes

The seven sizes from xxs to xxl, all using the same data.

Loading example…

SizesSourceStorybook

Shadows

The shadow elevation prop, inherited from Box, across all token levels.

Loading example…

ShadowsSourceStorybook

Controlled

Controlled active index — the parent drives which heading is highlighted.

Loading example…

ControlledSourceStorybook

Deep Nesting

Deeply nested headings — shows how depthOffset and minDepthToOffset affect indentation.

Loading example…

Deep NestingSourceStorybook

No Initial Active

No active selection — defaultActive is -1 so nothing is highlighted on mount.

Loading example…

No Initial ActiveSourceStorybook

Custom Control Props

Custom control content via getControlProps — adds an icon prefix to each entry.

Loading example…

Custom Control PropsSourceStorybook

Matrix

Full variant × size matrix for visual regression.

Loading example…

MatrixSourceStorybook

Styles

Per-slot styles targets individual parts — here the control and text.

Loading example…

StylesSourceStorybook

Themed

Accent color comes from Tamagui theme, not a public color prop.

Loading example…

ThemedSourceStorybook

Props

PropTypeDefaultDescription
activenumber | undefinedControlled index of the active heading
autoContrastboolean | undefinedNo-op cross-platform: the palette ramp already contrasts (parity only)
dataTableOfContentsItem[] | undefinedHeading data to render
defaultActivenumber | undefined-1Uncontrolled initial active index (-1 = none).
depthOffsetTableOfContentsDepthOffset | undefined
$xxs · $xs · $sm · $md · $lg · $xl · $xxl
"$lg"Left-padding added per depth level.
disabled systemboolean | undefined
getControlProps((payload: { active: boolean; data: TableOfContentsItem; }) => Partial<TocControlProps>) | undefinedPer-control prop overrides, computed per heading from its active state + data. The dynamic escape hatch over the `control` slot: it merges OVER `styles.control` (the "explicit beats sugar" rule), so per-item props always win.
initialDataTableOfContentsItem[] | undefinedAlias for `data`, accepted for Mantine parity
minDepthToOffsetnumber | undefined1Minimum depth that starts receiving the offset.
onChange((index: number) => void) | undefinedCalled with the index of the heading whose control was activated
radius systemstring | number | undefinedBorder radius of each control
shadow system"xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined
size systemnumber | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined
xxs · xs · sm · md · lg · xl · xxl
"md"Controls font-size and padding of every control.
styles systemSlotStyles<TableOfContentsStyles> | undefinedPer-slot style sugar — props spread onto the matching parts.
theme systemThemeName | null | undefinedApplies a theme to this element
variant systemTableOfContentsVariant | undefined
filled · light · none
"light"Active-item highlight style.

Style slots

Every part of TableOfContents can be styled through the styles prop. Explicit props on the component always win over slot styles.

SlotUsage
controlstyles={{ control: { … } }}
rootstyles={{ root: { … } }}
textstyles={{ text: { … } }}
Accessibility & DOM props (2)
PropType
keyKey | null | undefined
refRef<TamaguiElement> | undefined

Plus 497 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.