Nav List
Headless navigation list primitives for sidebars, page navigation, and grouped route lists.
Nav List in motion
When to Use
Use NavList for an ordinary list of destinations, such as sidebar links, settings pages, or grouped documentation routes. Use NavigationMenu when a top-level link opens a panel of more links, Menubar for application commands, and Listbox when the rows select values instead of navigating.
Features
The behavior Atom owns before your product adds appearance.
- Renders native navigation, list, list item, link, section, heading, and button semantics.
- Supports vertical and horizontal orientation metadata for styled layers.
- Supports active/current link state with configurable
aria-currenttokens. - Supports disabled links and disabled section interaction.
- Supports collapsible sections with controlled and uncontrolled open state.
- Keeps closing section content mounted through exit motion and exposes measured content-size hooks for styled disclosure animation.
- Supports
asChildandrendercomposition across every rendered part. - Keeps route behavior in consumer links while Atom owns ARIA and data attributes.
Import
Anatomy
API Reference
All DOM-rendering parts accept native props for their default element, except
for props Atom owns for behavior or accessibility. data-slot can be overridden
as a native data-* prop, but it is documented under data attributes because it
is primarily a styling hook.
Root
Contains the navigation list and provides orientation metadata to descendants.
Renders a nav by default.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
orientation | "vertical" | "horizontal" | "vertical" |
asChild | boolean | false |
render | RenderProp | - |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list" by default |
[data-orientation] | "vertical" | "horizontal" |
List
Renders the item list as ul by default, or ol when ordered is true.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
ordered | boolean | false |
asChild | boolean | false |
render | RenderProp | - |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-list" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-ordered] | Present when ordered is true |
Item
Wraps one navigation item. Renders an li by default.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
disabled | boolean | false |
asChild | boolean | false |
render | RenderProp | - |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-item" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-disabled] | Present when disabled |
Item disabled is a styling hook only. Pass disabled to NavList.Link to
prevent navigation.
Link
Renders a native link or composed route link. Renders an a by default.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
href | string | - |
active | boolean | false |
current | boolean | "page" | "step" | "location" | "date" | "time" | "page" |
disabled | boolean | false |
asChild | boolean | false |
render | RenderProp | - |
aria-current | boolean | "page" | "step" | "location" | "date" | "time" | active current value |
| ARIA attribute | Values |
|---|---|
aria-current | From aria-current, or from current when active |
aria-disabled | Present when disabled |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-link" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-active] | Present when active |
[data-current] | Present when active |
[data-disabled] | Present when disabled |
When disabled is true, href is omitted, clicks are prevented, and
tabIndex={-1} is rendered. aria-current overrides the value derived from
active and current.
Section
Provides grouped navigation state. Renders a section by default.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
collapsible | boolean | false |
open | boolean | - |
defaultOpen | boolean | true |
onOpenChange | (open: boolean) => void | - |
disabled | boolean | false |
asChild | boolean | false |
render | RenderProp | - |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-section" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-state] | "open" | "closed" |
[data-collapsible] | Present when collapsible |
[data-disabled] | Present when disabled |
Non-collapsible sections are always open. disabled prevents collapsible
sections from changing open state.
SectionLabel
Labels a section. Renders h2 by default and registers itself so section
content can reference the label.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
as | "h2" | "h3" | "h4" | "h5" | "h6" | "div" | "h2" |
asChild | boolean | false |
render | RenderProp | - |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-section-label" by default |
[data-orientation] | "vertical" | "horizontal" |
SectionTrigger
Toggles a collapsible section. Renders a button by default. When composed with
a non-button element, Atom adds button semantics and keyboard activation.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
onClick | MouseEventHandler<HTMLElement> | - |
onKeyDown | KeyboardEventHandler<HTMLElement> | - |
asChild | boolean | false |
render | RenderProp | - |
| ARIA attribute | Values |
|---|---|
aria-expanded | Section open state when collapsible |
aria-controls | Section content id when collapsible |
aria-disabled | Present for disabled non-native composed triggers |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-section-trigger" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-state] | "open" | "closed" |
[data-collapsible] | Present when the section is collapsible |
[data-disabled] | Present when the section is disabled |
For non-collapsible sections, the trigger remains rendered but does not expose expanded state or toggle behavior.
SectionContent
Contains section links. Renders a div by default.
| Prop | Type | Default |
|---|---|---|
children | ReactNode | - |
forceMount | boolean | false |
asChild | boolean | false |
render | RenderProp | - |
| ARIA attribute | Values |
|---|---|
aria-labelledby | Section label id, or trigger id for collapsible sections without a label |
| Data attribute | Values |
|---|---|
[data-slot] | "nav-list-section-content" by default |
[data-orientation] | "vertical" | "horizontal" |
[data-state] | "open" | "closed" |
[data-collapsible] | Present when the section is collapsible |
[data-initial-open] | Present while an initially open section has not transitioned |
During a transition, SectionContent exposes --content-height and
--content-width and remains mounted until a styled exit animation completes.
When forceMount is true, closed content becomes hidden after that animation.
Advanced compound components can use useNavListContext and
useNavListSectionContext; the matching providers and context value types are
also public exports.
Examples
Sidebar Navigation
Ordered Steps
Accessibility
NavList uses native nav,
list, list item, heading, button, and anchor
behavior. It does not implement roving focus because route navigation should
remain normal Tab navigation.
Active links expose aria-current using the current token, defaulting to
"page". Use current="step", "location", "date", or "time" when the
current item represents that ARIA current state instead of a page.
| Key | Description |
|---|---|
Tab | Moves through links and section triggers in document order |
Enter | Activates a focused link or section trigger |
Space | Toggles a focused section trigger |
Changelog
Unreleased
- Added public Agent Knowledge for component selection, required composition, recurring mistakes, and validation.
0.1.0
- Added native navigation list, collapsible section, and active link primitives.