A component to display a navigation sidebar.

Importing

The component can be imported via:

import { SideNav, SideNavGroup } from '@customerio/pluma-components/react';

Usage

SideNav is a vertical navigation component that contains NavItem, optionally wrapped in groups. The SideNav can be collapsed and expanded.

Loading editor

Default Collapsed State

Use defaultIsCollapsed to render the side navigation in a collapsed state initially. The user can still expand and collapse it using the toggle button.

Loading editor

Controlled Collapse State

For full control over the collapse state, use isCollapsed together with onCollapseChange.

Loading editor

What changed the state

onCollapseChange receives a second argument, { trigger, isPreview }, that says what changed the collapsed state:

table
triggerChange
buttonThe SideNav's Collapse or Expand button
edge-clickA click on an AppLayout nav edge
edge-dragA drag of an AppLayout nav edge
keyboardThe arrow keys, Home or End on an AppLayout nav edge
apiA call to the provider's setters, such as useToggleSideNav

isPreview is true for the changes a drag reports while it is still under way, and for the revert when a drag is cancelled. A drag that ends in the other state reports one more change with isPreview: false; a drag that ends where it started reports none. Skip previews when the change should only be saved once it is final:

<SideNavProvider
  onCollapseChange={(isCollapsed, { isPreview }) => {
    if (!isPreview) saveCollapsedPreference(isCollapsed);
  }}
>

The setters returned by useSetSideNavState and useToggleSideNav take the same details as an optional last argument, and report { trigger: 'api', isPreview: false } without it. Like the button, they report a change even when the value is already the one requested.

Not Collapsible

Set isCollapsible to false to hide the collapse/expand toggle button.

Loading editor

Groups

Use SideNavGroup to organize nav items into labeled sections. The title prop is optional — groups without a title still provide visual spacing between sections. Use isTitleVisible when a titled group needs to remain mounted while its items animate in or out, but its title should collapse.

Loading editor

Provider

SideNavProvider manages the side navigation's collapse state at the top of your layout, making it accessible to any nested component via context. This is useful when components outside the SideNav itself need to read or control the collapse state.

When a SideNav is rendered inside a SideNavProvider, it automatically inherits the provider's state instead of managing its own.

The provider accepts the same state props as SideNav: isCollapsed, onCollapseChange, defaultIsCollapsed, and isCollapsible.

It also holds whether an AppLayout nav is open over the content on small screens: isOpen, defaultIsOpen and onOpenChange, with useSetSideNavOpen to open or close it from anywhere inside the provider. Below 1024px, in an AppLayout with an AppLayoutNavToggle, where the nav opens over the content, useSideNavState reports isOverlay: true and the nav as neither collapsed nor collapsible. A SideNav outside an AppLayout collapses at every width. See "Small screens" in the AppLayout docs.

import {
  SideNavProvider,
  useSideNavState,
  useSetSideNavState,
  useToggleSideNav,
  useSetSideNavOpen,
} from '@customerio/pluma-components/react';

Usage

In this example, the SideNavProvider wraps the entire layout. A button in the main content area uses useToggleSideNav to control the side navigation without needing direct access to the SideNav component.

Loading editor

API

Default:'nav'

What element or component should be rendered.

Whether the side navigation is collapsed by default - use for uncontrolled collapse state when you want the side navigation to be in a specific state initially.

Whether the side navigation is collapsed. Use for controlled collapse state.

Default:true

Whether the side navigation can be collapsed and expanded. When false, the collapse/expand toggle button is hidden.

A callback function that is called when the collapse state changes. Use in combination with isCollapsed for controlled collapse state. The second argument says what changed it and whether the change is a drag preview.

Default:'div'

What element or component should be rendered.

Default:true

Whether the group title is visible. Use when the group remains mounted while its items animate in or out.

An optional title for the group, which can be used to provide context or categorization for the items within.

Whether the side navigation is collapsed by default - use for uncontrolled collapse state when you want the side navigation to be in a specific state initially.

Default:false

Whether the navigation starts open below the lg breakpoint. Use for uncontrolled open state.

Whether the side navigation is collapsed. Use for controlled collapse state.

Default:true

Whether the side navigation can be collapsed and expanded. When false, the collapse/expand toggle button is hidden.

Whether the navigation is open over the content, in an AppLayout below the lg breakpoint (1024px). Use for controlled open state. It has no effect from lg up, where the navigation is always in view.

A callback function that is called when the collapse state changes. Use in combination with isCollapsed for controlled collapse state. The second argument says what changed it and whether the change is a drag preview.

Called when the open state changes: from AppLayoutNavToggle, a dismissal (Escape or a click outside the navigation), the provider's setIsOpen and toggleIsOpen setters, and with false when the viewport crosses the lg breakpoint while the navigation is open.