@primer/react-brand
Version:
Primer Brand is a GitHub's design system for creating React-based marketing websites and digital experiences.
211 lines (179 loc) • 10.1 kB
Markdown
---
title: NavList
description: Use NavList to render vertical navigation with optional expandable groups.
keywords: ['navigation', 'vertical navigation', 'sidebar', 'nested navigation']
ready: true
source: https://github.com/primer/brand/tree/main/packages/react/src/NavList/NavList.tsx
storybook: '/brand/storybook/?path=/story/components-navlist--playground'
---
```js
import {NavList} from '@primer/react-brand'
```
## Examples
### Default
```jsx
<NavList aria-label="Docs navigation">
<NavList.Item href="#" aria-current="page">
Overview
</NavList.Item>
<NavList.Item href="#">Quickstart</NavList.Item>
<NavList.Item href="#">Install GitHub Copilot</NavList.Item>
<NavList.Item href="#">Configure your editor</NavList.Item>
<NavList.Item href="#">Manage policies</NavList.Item>
<NavList.Item href="#">Troubleshooting</NavList.Item>
</NavList>
```
### Groups
Use `NavList.Group` to organize related navigation items into labelled groups.
```jsx
<NavList aria-label="Section navigation">
<NavList.Group title="Products">
<NavList.Item href="#" aria-current="page">
Copilot
</NavList.Item>
<NavList.Item href="#">Codespaces</NavList.Item>
<NavList.Item href="#">Actions</NavList.Item>
<NavList.Item href="#">Packages</NavList.Item>
</NavList.Group>
<NavList.Group title="Collaboration">
<NavList.Item href="#">Pull requests</NavList.Item>
<NavList.Item href="#">Issues</NavList.Item>
<NavList.Item href="#">Discussions</NavList.Item>
</NavList.Group>
<NavList.Group title="Security">
<NavList.Item href="#">Overview</NavList.Item>
<NavList.Item href="#">Secret scanning</NavList.Item>
<NavList.Item href="#">Code scanning</NavList.Item>
</NavList.Group>
</NavList>
```
### Nested disclosure
Add `NavList.SubNav` to a `NavList.Item` when an item needs to expand and collapse nested navigation links.
```jsx
<NavList aria-label="Nested navigation">
<NavList.Group title="Collaboration">
<NavList.Item defaultExpanded>
Pull requests
<NavList.SubNav>
<NavList.Item href="#" aria-current="page">
Review pull requests
</NavList.Item>
<NavList.Item href="#">Use suggested changes</NavList.Item>
<NavList.Item href="#">Configure rulesets</NavList.Item>
</NavList.SubNav>
</NavList.Item>
<NavList.Item>
Branches
<NavList.SubNav>
<NavList.Item href="#">Overview</NavList.Item>
<NavList.Item href="#">Protection rules</NavList.Item>
</NavList.SubNav>
</NavList.Item>
</NavList.Group>
</NavList>
```
### Up to five navigation levels
`NavList` can include up to five levels when a page hierarchy requires it. Use the fewest levels needed; levels one through four can optionally expand or collapse, and level five is reserved for leaf article links.
```jsx
<NavList aria-label="Five-level navigation">
<NavList.Item defaultExpanded>
GitHub Copilot
<NavList.SubNav>
<NavList.Item defaultExpanded>
Guides
<NavList.SubNav>
<NavList.Item defaultExpanded>
Agents
<NavList.SubNav>
<NavList.Item defaultExpanded>
Build an agent
<NavList.SubNav>
<NavList.Item href="#" aria-current="page">
Create a tool
</NavList.Item>
<NavList.Item href="#">Add memory</NavList.Item>
<NavList.Item href="#">Debug prompts</NavList.Item>
<NavList.Item href="#">Deploy safely</NavList.Item>
</NavList.SubNav>
</NavList.Item>
<NavList.Item href="#">Customize an agent</NavList.Item>
<NavList.Item href="#">Debug an agent</NavList.Item>
</NavList.SubNav>
</NavList.Item>
<NavList.Item>
Extensions
<NavList.SubNav>
<NavList.Item href="#">Install an extension</NavList.Item>
<NavList.Item href="#">Publish an extension</NavList.Item>
<NavList.Item href="#">Manage permissions</NavList.Item>
</NavList.SubNav>
</NavList.Item>
</NavList.SubNav>
</NavList.Item>
<NavList.Item>
Administration
<NavList.SubNav>
<NavList.Item href="#">Overview</NavList.Item>
<NavList.Item href="#">Policies</NavList.Item>
<NavList.Item href="#">Audit log</NavList.Item>
</NavList.SubNav>
</NavList.Item>
</NavList.SubNav>
</NavList.Item>
<NavList.Item>
Code review
<NavList.SubNav>
<NavList.Item href="#">Overview</NavList.Item>
<NavList.Item href="#">Review pull requests</NavList.Item>
<NavList.Item href="#">Use suggested changes</NavList.Item>
</NavList.SubNav>
</NavList.Item>
</NavList>
```
### With visuals
Use `leadingVisual` and `trailingVisual` to add icons to the label area. Visuals are additive: they do not replace disclosure triangles, change item sizing, or move the active and inactive row alignment.
```jsx
<NavList aria-label="Visual navigation">
<NavList.Item href="#" aria-current="page" leadingVisual={BookIcon} trailingVisual={<KebabHorizontalIcon />}>
GitHub Copilot
</NavList.Item>
</NavList>
```
## Accessibility
Give each `NavList` a clear `aria-label`, especially when the page includes more than one navigation landmark.
Use `aria-current="page"` on the link for the current page. Only apply `aria-current` to leaf items that navigate somewhere, not to disclosure rows with nested items.
Keep group titles and disclosure labels short and descriptive. Items with `NavList.SubNav` must include visible label text so people can understand what will expand.
## Component props
### NavList `Required`
| name | type | default | required | description |
| ----------------- | ----------- | ------- | -------- | ----------------------------------------------------- |
| `children` | `ReactNode` | | `true` | `NavList.Item` and `NavList.Group` nodes |
| `aria-label` | `string` | | `true` | Accessible label for the navigation landmark |
| `aria-labelledby` | `string` | | `false` | ID of the element that labels the navigation landmark |
| `className` | `string` | | `false` | Sets a custom class on the `nav` element |
Forwards all standard HTML attributes for `<nav>` elements.
### NavList.Item `Required`
| name | type | default | required | description |
| ------------------ | ------------------------------------------------------------------------- | ------- | -------- | ------------------------------------------------------------------------------------------ |
| `as` | `'a' \| 'button'` | `'a'` | `false` | Element used for leaf items |
| `children` | `ReactNode` | | `true` | Item label and optional `NavList.SubNav` for nested disclosure |
| `href` | `string` | | `false` | URL for leaf items when rendering as an anchor |
| `aria-current` | `'page' \| 'step' \| 'location' \| 'date' \| 'time' \| 'true' \| 'false'` | | `false` | Marks a leaf item as current |
| `defaultExpanded` | `boolean` | `false` | `false` | Opens nested `NavList.SubNav` by default |
| `expanded` | `boolean` | | `false` | Controls the nested `NavList.SubNav` expanded state |
| `onExpandedChange` | `(expanded) => void` | | `false` | Called when the nested `NavList.SubNav` expanded state changes |
| `leadingVisual` | `ReactElement \| Icon` | | `false` | Visual rendered before the label |
| `trailingVisual` | `ReactElement \| Icon` | | `false` | Visual rendered after the label |
| `disabled` | `boolean` | `false` | `false` | Disables the item. Leaf links receive `aria-disabled`; disclosure buttons receive disabled |
Forwards props to the rendered leaf link or disclosure button.
### NavList.Group
| name | type | default | required | description |
| ----------- | ----------- | ------- | -------- | ------------------------------------------ |
| `title` | `ReactNode` | | `false` | Heading text for the group |
| `children` | `ReactNode` | | `true` | `NavList.Item` nodes |
| `className` | `string` | | `false` | Sets a custom class on the group list item |
### NavList.SubNav
| name | type | default | required | description |
| ----------- | ----------- | ------- | -------- | -------------------------------------- |
| `children` | `ReactNode` | | `true` | Nested `NavList.Item` nodes |
| `className` | `string` | | `false` | Sets a custom class on the nested `ul` |