Sidebar Navigation
A highly composable, hierarchical, vertical side navigation component.
Import#
import { SidebarNavigation } from '@volue/wave-react';// Optional hookimport { useSidebarNavigationContext } from '@volue/wave-react';// Optional set of variablesimport {SIDEBAR_NAVIGATION_MEDIUM_WIDTH_EXPANDED,SIDEBAR_NAVIGATION_MEDIUM_WIDTH_COLLAPSED,SIDEBAR_NAVIGATION_SMALL_WIDTH_EXPANDED,SIDEBAR_NAVIGATION_SMALL_WIDTH_COLLAPSED} from '@volue/wave-react';
Sidebar Navigation is a compound component that consists of multiple parts to help you create different kinds of navigation.
- ​
SidebarNavigation.Root: The wrapper that contains all the parts of a navigation and provides context for its children. - ​
SidebarNavigation.Header: The header of the navigation used to render components such as Logo andSidebarNavigation.AppTitle. - ​
SidebarNavigation.AppTitle: Wrapper for the app title. - ​
SidebarNavigation.Body: The scrollable body of the navigation. Used to render sections of navigation items. - ​
SidebarNavigation.Section: Signifies a segment of the navigation. - ​
SidebarNavigation.Items: Container for the navigation items. - ​
SidebarNavigation.Item: An individual navigation item. Each item is a link or action a user can take. - ​
- ​
SidebarNavigation.Group: An expandable grouping of nestedSidebarNavigation.Items. - ​
SidebarNavigation.Footer: The persistent footer at the bottom of the navigation. Typically used to render user-related items. - ​
SidebarNavigation.Toggle: The button that toggles between expanded and collapsed states of the navigation.
Examples#
Examples below include maxHeight: 60vh CSS rule, to ensure optimal docs-browsing experience.
It should not be added in a real app environment.
Due to some limitations of the playground environment, it's recommended to browse fullscreen examples in Storybook​.
Default#
Sidebar Navigation is commonly used to display the primary navigation in an application with sidebar-based layout. The navigation items should represent different areas of your application, except for the footer part which is typically used for user actions such as logout. You can nest navigation items within sections and collapsible groups, to create logical grouping of navigation items.
- ​To provide the structure for the navigation component, including the actual sidebar use the App Frame or App Frame With Sidebar components.
- ​
SidebarNavigation.Itemmust be used insideSidebarNavigation.Items. - ​
SidebarNavigation.Itemrequires both label and icon (or custom visual) due to the visual style of the collapsed state. - ​Nesting
SidebarNavigation.GroupinsideSidebarNavigation.Groupis not supported. - ​Use
isActiveproperty onSidebarNavigation.Itemto indicate that the item represents the current page. The item will be highlighted and scrolled into view. If the item is withinSidebarNavigation.Group, the group will automatically open. - ​If navigation items have too long labels, they truncate. The full label is revealed via a Tooltip. However, it’s best to avoid long labels: keep them succinct and scannable.
- ​
SidebarNavigation.Bodycan vertically scroll for longer navigation lists. Order items by importance, so that the higher priority items are visible without scrolling.
The example below shows all components composed together.
With content overlap#
By default, when you expand the sidebar navigation, it pushes app contents so that it's always visible.
In certain type of applications, for example where the entire viewport is a map canvas, you may want the sidebar navigation to slide over the map in its expanded state.
To do so, set mode property to overlayContent.
It's also recommended to set the toggleOnHover property, so that it's possible to toggle the sidebar navigation state with a convenient hover interaction.
Hover interaction will be enabled only for users whose primary input device is capable of hovering. Otherwise (i.e. touchscreen device) the component will fallback to show SidebarNavigation.Toggle at the bottom of the navigation panel.
Small size#
Sidebar navigation is also available in small size for data-heavy or complex applications where increased density improves the user experience.
Mobile version#
On small screens, a mobile version of the navigation should be displayed inside a Drawer with overlay.
Drawer.Trigger is responsible for showing the mobile navigation and Drawer.Close acts as a dismiss button. Drawer component comes with many accessibility features out of the box.
Hidden utility is used to control the presence of both mobile and desktop navigation experiences based on specified breakpoints.
Desktop navigation within the AppFrame.Sidebar is present on large viewport and above, while the mobile navigation toggle is only visible on viewports below large.
Non-collapsible#
For scenarios where collapsible navigation is unnecessary, you can use the SidebarNavigation component without the ability to collapse or expand.
This allows for simplifying the interface by using SidebarNavigation.Item components without icons or other leading visual elements.
Use visuals consistently. Avoid mixing items that have leading visuals with items that don't.
When using Nav Bar as your primary navigation, non-collapsible sidebar navigation can also be used as a secondary level navigation to alternate among related views within the same context.
With routing#
If you need to use the Link component provided by your routing package (e.g. React Router​ or Next.js​), it's recommended to compose it with SidebarNavigation.Item via a custom component:
import { Link, useMatch, useResolvedPath } from 'react-router-dom';import { SidebarNavigation } from '@volue/wave-react';function SidebarNavigationItem({ to, ...props }) {const resolved = useResolvedPath(to);const isActive = Boolean(useMatch({ path: resolved.pathname, end: true }));return (<SidebarNavigation.Item as={Link} to={to} isActive={isActive} {...props} />);}function App() {return (<SidebarNavigation.Root><SidebarNavigation.Header /><SidebarNavigation.Body><SidebarNavigation.Items><SidebarNavigationItem label="Dashboard" iconName="home" to="/" /><SidebarNavigationItem label="Maps" iconName="themeMap" to="/maps" /><SidebarNavigationItemlabel="Attachments"iconName="attachment"to="/attachments"/></SidebarNavigation.Items></SidebarNavigation.Body><SidebarNavigation.Footer /></SidebarNavigation.Root>);}
API Reference#
SidebarNavigation.Root#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
isExpanded | boolean | true |
defaultIsExpanded | boolean | No default value |
onIsExpandedChange | function | No default value |
size | enum | "medium" |
expandedWidth | CSSProperties['width'] | "17rem" |
withMotion | boolean | true |
withSeparator | boolean | false |
toggleOnHover | boolean | false |
mode | enum | pushContent |
hoverArea | enum | No default value |
elevation | enum | "none" |
aria-label* | string | No default value |
SidebarNavigation.Header#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
SidebarNavigation.AppTitle#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
variant | enum | delta |
SidebarNavigation.Body#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
gap | SpacingToken | "spacingM" |
SidebarNavigation.Section#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
gap | SpacingToken | "spacingS" |
title* | string | No default value |
SidebarNavigation.Items#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
gap | SpacingToken | "spacingXs" |
SidebarNavigation.Item#
Prop | Type | Default |
|---|---|---|
as | enum | button |
css | StitchesCss | No default value |
label* | string | No default value |
iconName | IconToken | No default value |
isActive | boolean | false |
isDisabled | boolean | false |
leadingVisual | React.ReactNode | No default value |
trailingVisual | React.ReactNode | No default value |
SidebarNavigation.ItemLabel#
Prop | Type | Default |
|---|---|---|
as | enum | div |
css | StitchesCss | No default value |
color | enum | "neutral" |
size | enum | "medium" |
children | React.ReactNode | No default value |
SidebarNavigation.Group#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
label* | string | No default value |
iconName* | IconToken | No default value |
defaultIsOpen | boolean | false |
gap | SpacingToken | "spacingXs" |
leadingVisual | React.ReactNode | No default value |
isDisabled | boolean | false |
SidebarNavigation.Footer#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
gap | SpacingToken | "spacingM" |
SidebarNavigation.Toggle#
Prop | Type | Default |
|---|---|---|
css | StitchesCss | No default value |
label* | string | No default value |