A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.
Content
NavigationTree follows the Collection Components API, accepting both static and dynamic collections. The example above shows a static collection. This example shows a dynamic collection, passing a list of objects to the items prop and a function to render the children.
import {NavigationTree, NavigationTreeItem, NavigationTreeItemContent, NavigationTreeItemLink} from './NavigationTree';
import {RoutedNavigationTree} from './RoutedNavigationTree';
function Example() {
let items = [
{id: 'overview', url: '/overview', label: 'Overview'},
{id: 'reports', url: '/reports', label: 'Reports'},
{id: 'settings', url: '/settings', label: 'Settings'}
];
return (
<RoutedNavigationTree defaultSelectedRoute="/reports">
{({selectedRoute}) => (
<NavigationTree aria-label="Sections" items={items} selectedRoute={selectedRoute}>
{item => (
<NavigationTreeItem href={item.url} textValue={item.label}>
<NavigationTreeItemContent>
<NavigationTreeItemLink>{item.label}</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
)}
</NavigationTree>
)}
</RoutedNavigationTree>
);
}
Accessibility
NavigationTree renders as a tree so keyboard users can navigate and expand the hierarchy. When it acts as the main navigation for a page, place it inside a navigation landmark: wrap the NavigationTree in a <nav> element with an aria-label so assistive technology users can quickly find it.Sections
Use NavigationTreeSection to group related items, with an optional NavigationTreeHeader to label each group. Sections without a header must have an aria-label.
import {NavigationTree, NavigationTreeItem, NavigationTreeItemContent, NavigationTreeItemLink, NavigationTreeSection, NavigationTreeHeader} from './NavigationTree';
import {RoutedNavigationTree} from './RoutedNavigationTree';
<RoutedNavigationTree defaultSelectedRoute="/projects/apollo">
{({selectedRoute}) => (
<NavigationTree aria-label="Workspace" selectedRoute={selectedRoute}>
<NavigationTreeSection>
<NavigationTreeHeader>Personal</NavigationTreeHeader>
<NavigationTreeItem href="/home" textValue="Home">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Home</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
<NavigationTreeItem href="/starred" textValue="Starred">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Starred</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
</NavigationTreeSection>
<NavigationTreeSection>
<NavigationTreeHeader>Projects</NavigationTreeHeader>
<NavigationTreeItem href="/projects/apollo" textValue="Apollo">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Apollo</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
<NavigationTreeItem href="/projects/gemini" textValue="Gemini">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Gemini</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
</NavigationTreeSection>
</NavigationTree>
)}
</RoutedNavigationTree>
Current route
Each NavigationTreeItem accepts an href. Set the selectedRoute prop on the NavigationTree to the current page's path, and the item whose href matches is marked with aria-current="page" (and a data-current attribute for styling).
Combine NavigationTree with a client side router by wrapping your app in a RouterProvider so that activating a link updates the route. Then set selectedRoute. In this example the router navigation is stored in local state to show the current route updating as you activate links.
import {NavigationTree, NavigationTreeItem, NavigationTreeItemContent, NavigationTreeItemLink} from './NavigationTree';
import {RouterProvider} from 'react-aria-components';
import {useState} from 'react';
function Example() {
let [route, setRoute] = useState('/inbox');
return (
<RouterProvider navigate={setRoute}>
<NavigationTree aria-label="Mail" selectedRoute={route}>
<NavigationTreeItem href="/inbox" textValue="Inbox">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Inbox</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
<NavigationTreeItem href="/drafts" textValue="Drafts">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Drafts</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
<NavigationTreeItem href="/sent" textValue="Sent">
<NavigationTreeItemContent>
<NavigationTreeItemLink>Sent</NavigationTreeItemLink>
</NavigationTreeItemContent>
</NavigationTreeItem>
</NavigationTree>
</RouterProvider>
);
}
API
<NavigationTree>
<NavigationTreeSection>
<NavigationTreeHeader />
<NavigationTreeItem>
<NavigationTreeItemContent>
<Link />
<Button slot="chevron" />
</NavigationTreeItemContent>
</NavigationTreeItem>
</NavigationTreeSection>
</NavigationTree>
NavigationTree
A NavigationTree provides users with a way to navigate a nested, hierarchical set of links.
| Name | Type | |
|---|---|---|
selectedRoute | string | null | |
The route that is currently selected, matched against each item's | ||
expandedKeys | Iterable | |
The currently expanded keys in the collection (controlled). | ||
defaultExpandedKeys | Iterable | |
The initial expanded keys in the collection (uncontrolled). | ||
children | ReactNode | | |
The contents of the collection. | ||
items | Iterable | |
Item objects in the collection. | ||
dependencies | ReadonlyArray | |
Values that should invalidate the item cache when using dynamic collections. | ||
disabledKeys | Iterable | |
The item keys that are disabled. These items cannot be selected, focused, or otherwise interacted with. | ||
Default className: react-aria-NavigationTree
| Render Prop | CSS Selector |
|---|---|
isEmpty | CSS Selector: [data-empty]
|
| Whether the tree has no items and should display its empty state. | |
isFocused | CSS Selector: [data-focused]
|
| Whether the tree is currently focused. | |
isFocusVisible | CSS Selector: [data-focus-visible]
|
| Whether the tree is currently keyboard focused. | |
state | CSS Selector: — |
| State of the tree. | |
NavigationTreeItem
A NavigationTreeItem represents an individual item in a NavigationTree.
| Name | Type | |
|---|---|---|
children | ReactNode | |
The content of the side nav item along with any nested children. Supports static nested side nav items or use of a Collection to dynamically render nested side nav items. | ||
id | Key | |
The unique id of the tree row. | ||
textValue | string | |
A string representation of the tree item's contents, used for features like typeahead. | ||
isDisabled | boolean | |
Whether the item is disabled. | ||
hasChildItems | boolean | |
Whether this item has children, even if not loaded yet. | ||
Default className: react-aria-NavigationTreeItem
| Render Prop | CSS Selector |
|---|---|
isCurrent | CSS Selector: [data-current]
|
Whether this item is the current route (its href matches the NavigationTree's
selectedRoute). | |
isCurrentAncestor | CSS Selector: [data-current-ancestor]
|
| Whether this item is an ancestor of the current-route item (at any level, regardless of whether it is expanded or collapsed). | |
isExpanded | CSS Selector: [data-expanded]
|
| Whether the tree item is expanded. | |
hasChildItems | CSS Selector: [data-has-child-items]
|
| Whether the tree item has child tree items. | |
level | CSS Selector: [data-level="number"]
|
| What level the tree item has within the tree. | |
isFocusVisibleWithin | CSS Selector: [data-focus-visible-within]
|
| Whether the tree item's children have keyboard focus. | |
state | CSS Selector: — |
| The state of the tree. | |
id | CSS Selector: — |
| The unique id of the tree row. | |
isHovered | CSS Selector: [data-hovered]
|
| Whether the item is currently hovered with a mouse. | |
isPressed | CSS Selector: [data-pressed]
|
| Whether the item is currently in a pressed state. | |
isSelected | CSS Selector: [data-selected]
|
| Whether the item is currently selected. | |
isFocused | CSS Selector: [data-focused]
|
| Whether the item is currently focused. | |
isFocusVisible | CSS Selector: [data-focus-visible]
|
| Whether the item is currently keyboard focused. | |
isDisabled | CSS Selector: [data-disabled]
|
Whether the item is non-interactive, i.e. both selection and actions are disabled and the item
may not be focused. Dependent on disabledKeys and disabledBehavior. | |
selectionMode | CSS Selector: [data-selection-mode="single | multiple"]
|
| The type of selection that is allowed in the collection. | |
selectionBehavior | CSS Selector: — |
| The selection behavior for the collection. | |
NavigationTreeItemContent
| Name | Type | |
|---|---|---|
children | ChildrenOrFunction | |
The children of the component. A function may be provided to alter the children based on component state. | ||
NavigationTreeSection
A NavigationTreeSection represents a section within a NavigationTree.
| Name | Type | |
|---|---|---|
id | Key | |
The unique id of the section. | ||
children | ReactNode | | |
Static child items or a function to render children. | ||
items | Iterable | |
Item objects in the section. | ||
dependencies | ReadonlyArray | |
Values that should invalidate the item cache when using dynamic collections. | ||
NavigationTreeHeader
A NavigationTreeHeader renders the header of a NavigationTreeSection.
| Name | Type | |
|---|---|---|
children | ReactNode | |
The children of the component. | ||