Sidebar Navigation

A highly composable, hierarchical, vertical side navigation component to help users navigate through major areas of the app.

Import#

import { SidebarNavigation } from '@volue/wave-react';
// Optional hook
import { useSidebarNavigationContext } from '@volue/wave-react';
// Optional set of variables
import {
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: 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 and SidebarNavigation.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.ItemLabel: An additional descriptor for navigation item. It renders Label in expanded state and switches to Hint Dot in collapsed state.
  • ​
    SidebarNavigation.Group: An expandable grouping of nested SidebarNavigation.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 used to display the primary navigation in the sidebar of an application. 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 component.
  • ​
    SidebarNavigation.Item must be used inside SidebarNavigation.Items.
  • ​
    SidebarNavigation.Item requires both label and icon (or custom visual) due to the visual style of the collapsed state.
  • ​
    Nesting SidebarNavigation.Group inside SidebarNavigation.Group is not supported.
  • ​
    Use isActive property on SidebarNavigation.Item to indicate that the item represents the current page. The item will be highlighted and scrolled into view. If the item is within SidebarNavigation.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.Body can vertically scroll for longer navigation lists. Order items by importance, so that the higher priority items are visible without scrolling.

Navigation should be used to move between major areas of your application. To alternate among related views within the same context, you can use the Tabs component.

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 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.

See complete example in Storybook

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.

With routing#

If you need to use the Link component provided by your routing package such as React Router​ 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>
<SidebarNavigation.Header />
<SidebarNavigation.Body>
<SidebarNavigation.Items>
<SidebarNavigationItem label="Dashboard" iconName="home" to="/" />
<SidebarNavigationItem label="Maps" iconName="themeMap" to="/maps" />
<SidebarNavigationItem
label="Attachments"
iconName="attachment"
to="/attachments"
/>
</SidebarNavigation.Items>
</SidebarNavigation.Body>
<SidebarNavigation.Footer />
</SidebarNavigation>
);
}

API Reference#

SidebarNavigation#

Prop
Type
Default
css
StitchesCss
No default value
isExpanded
boolean
false
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
m
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