Contents Nav

Page outline and catalogue index composed with List Item. Use toc for on-page headings with optional nest line and scroll spy. Use index for sectioned side navigation.

Also known as: toc, table of contents, on this page, catalogue index, side nav, outline, contents

Installation

Install with the CLI, or copy the component source into your project.

Add contents-nav (npm)

npx --yes -p @default-file/ui df-ui add contents-nav

TOC

On-page outline with nested muted rows and a nest guide line. scrollSpy is off in the demo so the selected row stays stable.

TOC without nest line

Same toc tree with nestLine false so nested rows indent without a guide line.

Index grouped

Catalogue-style index with section labels and top dividers between groups.

Index flat

Flat index list without section labels.

Composition

Build the toc from parts. ListItemNest controls the nest guide line per group.

Index composition

Index built from sections, items, and a separator for flat groupings.

Properties

Page outline and catalogue index composed with List Item. Use variant toc for on-page headings with nested rows, optional nest guide line, and scroll spy. Use variant index for sectioned side navigation. Pass scrollRoot for the host scrollport. Compose with ContentsNavHeading, ContentsNavSection, ContentsNavItem, and ListItemNest, or pass items and sections.

ContentsNav

Root nav. toc defaults nestLine and scrollSpy on. index defaults them off and uses section labels.

PropTypeDefaultNotes
variant"toc" | "index""toc"toc is the on-page outline. index is the catalogue or side index.
titleReactNode-Optional heading above the list. Typical for toc (for example On this page).
itemsContentsNavItemData[]-Tree or flat rows. Each item needs id and title. Optional href, children, disabled, and readOnly. toc defaults href to #id when omitted. Pass href null for a non-link row. readOnly keeps size and selected chrome without hover or activation.
sectionsContentsNavSectionData[]-Grouped index sections with label, optional divided, and items. Used when variant is index and layout is grouped.
layout"grouped" | "flat""grouped"Index list shape. grouped renders sections. flat renders items only.
nestLineboolean-Default guide line for nested groups. Defaults true for toc and false for index. Override per group with ListItemNest line.
scrollSpyboolean-Update activeId from scroll position. Defaults true for toc and false for index.
scrollRootElement | RefObject<Element | null> | (() => Element | null)-Scrollport used by scroll spy. Defaults to document.scrollingElement. Pass your app scroller when the page does not scroll on the document.
spyRationumber0.25Fraction of the scrollport height used as the primary spy marker.
activeIdstring-Controlled active item id.
defaultActiveIdstring-Uncontrolled initial active id.
onActiveIdChange(id: string) => void-Called when the active id changes from spy or selection.
itemVariant"accent" | "muted""muted"Default List Item variant for rows.
itemSize"xs" | "sm" | "md" | "lg"-Default List Item size for top-level rows. Defaults to "sm" for toc and "md" for index.
nestItemSize"xs" | "sm" | "md" | "lg""xs"Default List Item size for nested rows.
itemChromeListItemChromeProps-Default List Item chrome for every row (padding, gap, type size/family/weight/color, radius, fills, and stroke). Applies to composed ContentsNavItem rows and data-driven branches. Per-item chrome props on ContentsNavItem win. See List Item for the full chrome contract.
nestChromeListItemNestChromeProps-Default ListItemNest chrome for data-driven child groups (indent, pad, gap, lineWidth, lineColor). nestLine still controls whether the guide line paints. Composed ListItemNest instances set their own props.
renderItem(item, ctx) => ReactElement-Render a custom host for each data item (for example a router Link). The host is painted with List Item via asChild.
childrenReactNode-Composition mode. Use ContentsNavHeading, ContentsNavSection, ContentsNavItem, and ListItemNest instead of items or sections.
classNamestring-Additional styles on the nav host.

ContentsNavHeading

Title row above the list (data-df contents-nav-heading).

PropTypeDefaultNotes
childrenReactNode-Heading text.
classNamestring-Additional styles.

ContentsNavSection

Index section with ListItemLabel nav and optional top divider.

PropTypeDefaultNotes
labelReactNode-Section title rendered with ListItemLabel variant nav.
dividedbooleanfalseWhen true, adds a top hairline and spacing above the section.
childrenReactNode-Section rows.

ContentsNavItem

List Item row for a nav entry. Also accepts List Item chrome props such as padding, gap, fontSize, fills, stroke, and radius. Per-item chrome wins over ContentsNav itemChrome. See List Item.

PropTypeDefaultNotes
activeboolean-Selected appearance. When omitted and itemId is set, matches activeId from context.
itemIdstring-Id used for selection and scroll spy matching.
hrefstring-Renders an anchor row when asChild is false.
asChildbooleanfalsePaint List Item onto a single child element such as a link.
disabledbooleanfalseNon-interactive row. Forwarded to List Item. Dims the row and blocks activation.
readOnlybooleanfalsePresentational row. Forwarded to List Item. Keeps size, variant, and selected appearance with no hover, press, or activation.
size"xs" | "sm" | "md" | "lg"-Overrides the size default. Outside ListItemNest, defaults to itemSize. Inside ListItemNest, defaults to nestItemSize.
variant"accent" | "muted"-Overrides the ContentsNav itemVariant default.

ContentsNavSeparator

Horizontal hairline between flat index groups.

PropTypeDefaultNotes
classNamestring-Additional styles.

Tokens

Theme defaults live on :root. Override these globally or on a local host.

TokenTypeDefaultNotes
--df-contents-nav-gapCSS length-Gap between top-level children. Index defaults to 0 so sections own rhythm.
--df-contents-nav-branch-gapCSS length-Gap between a row and its nested group.
--df-contents-nav-heading-margin-bottomCSS length-Space under ContentsNavHeading.
--df-list-item-nest-indentCSS length-Outer inset on ListItemNest. Set by the indent prop.
--df-list-item-nest-padCSS length-Inner pad after the nest guide line. Set by the pad prop.
--df-list-item-nest-gapCSS length-Gap between nested rows. Set by the gap prop on ListItemNest.
--df-list-item-nest-line-widthCSS length-Nest guide line thickness. Set by lineWidth.
--df-list-item-nest-line-colorCSS color-Nest guide line color. Set by lineColor.