Components Navigation
Sidebar
StableComposable primitives for application sidebar navigation, with an icon-only collapsed mode.
Sidebar provides the parts of a navigation sidebar (header, groups, items, footer and a collapse toggle) without positioning itself. Place it in your existing layout, fixed, sticky or in a grid, so product shells such as eSignify’s 18rem ↔ 5rem collapsing sidebar keep their structure. Use activeStyle="inverted" for a filled active item.
Overview
import { Icon, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarHeader, SidebarItem } from '@bindshq/stance-react';
export function Basic() {
return (
<div style={{ height: 440, display: 'flex' }}>
<Sidebar aria-label="Dashboard">
<SidebarHeader>
<strong>Binds</strong>
</SidebarHeader>
<SidebarContent>
<SidebarGroup label="Workspace">
<SidebarItem href="#dashboard" icon={<Icon name="home" />} active>
Dashboard
</SidebarItem>
<SidebarItem href="#templates" icon={<Icon name="file-text" />}>
My Templates
</SidebarItem>
<SidebarItem href="#users" icon={<Icon name="users" />}>
Org Users
</SidebarItem>
<SidebarItem href="#integrations" icon={<Icon name="link" />}>
Integrations
</SidebarItem>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarGroup>
<SidebarItem href="#settings" icon={<Icon name="settings" />}>
Settings
</SidebarItem>
</SidebarGroup>
</SidebarFooter>
</Sidebar>
</div>
);
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
Import
import { Sidebar, SidebarHeader, SidebarContent, SidebarGroup, SidebarItem, SidebarFooter, SidebarToggle, useSidebar } from '@bindshq/stance-react';Platforms
Sidebar has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
import { Sidebar, SidebarHeader, SidebarContent, SidebarGroup, SidebarItem, SidebarFooter, SidebarToggle, useSidebar } from '@bindshq/stance-react';Examples
Collapsible (eSignify style)
Inverted active item; the toggle switches between 18rem and 5rem, showing icons with titles.
import { useState } from 'react';
import { Icon, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarHeader, SidebarItem, SidebarToggle } from '@bindshq/stance-react';
export function Collapsible() {
const [collapsed, setCollapsed] = useState(false);
return (
<div style={{ height: 440, display: 'flex' }}>
<Sidebar
aria-label="Dashboard"
activeStyle="inverted"
collapsed={collapsed}
onCollapsedChange={setCollapsed}
>
<SidebarHeader style={{ justifyContent: collapsed ? 'center' : 'space-between' }}>
{!collapsed && <strong>eSignify</strong>}
<SidebarToggle />
</SidebarHeader>
<SidebarContent>
<SidebarGroup>
<SidebarItem href="#dashboard" icon={<Icon name="home" />} active>
Dashboard
</SidebarItem>
<SidebarItem href="#templates" icon={<Icon name="file-text" />}>
My Templates
</SidebarItem>
<SidebarItem href="#users" icon={<Icon name="users" />}>
Org Users
</SidebarItem>
<SidebarItem href="#integrations" icon={<Icon name="link" />}>
Integrations
</SidebarItem>
<SidebarItem href="#settings" icon={<Icon name="settings" />}>
Settings
</SidebarItem>
</SidebarGroup>
</SidebarContent>
<SidebarFooter>
<SidebarGroup>
<SidebarItem icon={<Icon name="log-out" />} onClick={() => {}}>
Log out
</SidebarItem>
</SidebarGroup>
</SidebarFooter>
</Sidebar>
</div>
);
}import { Icon, Sidebar, SidebarContent, SidebarGroup, SidebarItem } from '@bindshq/stance-react';
export function Groups() {
return (
<div style={{ height: 400, display: 'flex' }}>
<Sidebar aria-label="Admin">
<SidebarContent>
<SidebarGroup label="Overview">
<SidebarItem href="#dashboard" icon={<Icon name="bar-chart" />} active>
Dashboard
</SidebarItem>
<SidebarItem href="#companies" icon={<Icon name="building" />} badge={12}>
Companies
</SidebarItem>
</SidebarGroup>
<SidebarGroup label="Library" collapsible>
<SidebarItem href="#gallery" icon={<Icon name="image" />}>
Image gallery
</SidebarItem>
<SidebarItem href="#templates" icon={<Icon name="layout-grid" />}>
Global templates
</SidebarItem>
</SidebarGroup>
<SidebarGroup label="Configuration" collapsible defaultOpen={false}>
<SidebarItem href="#azure" icon={<Icon name="shield" />}>
Azure setup
</SidebarItem>
</SidebarGroup>
</SidebarContent>
</Sidebar>
</div>
);
}API reference
Sidebar
| Prop | Type | Default | Description |
|---|---|---|---|
collapsed | boolean | None | Controlled icon-only state. |
defaultCollapsed | boolean | false | Initial collapsed state. |
onCollapsedChange | (collapsed: boolean) => void | None | Called when the toggle is used. |
as | 'nav' | 'aside' | 'div' | 'nav' | Root element; nav creates a navigation landmark. |
aria-label | string | 'Main' | Landmark name. |
activeStyle | 'subtle' | 'inverted' | 'subtle' | Tinted or filled active item. |
width | string | '18rem' | Expanded width (sets --st-sidebar-width). |
collapsedWidth | string | '5rem' | Collapsed width. |
SidebarGroup
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | None | Group heading; names the list. |
collapsible | boolean | false | Heading becomes a disclosure button. |
open / defaultOpen / onOpenChange | boolean / boolean / (open) => void | true | Group open state. |
SidebarItem
| Prop | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | None | Shown in both states; required for a useful collapsed sidebar. |
active | boolean | false | Current page: aria-current="page" on links. |
badge | ReactNode | None | Trailing count; becomes a dot when collapsed. |
href | string | None | Renders a link. Without href it renders a button. |
asChild | boolean | false | Render your router link. |
disabled | boolean | None | Disables a button item. |
SidebarToggle
| Prop | Type | Default | Description |
|---|---|---|---|
expandLabel / collapseLabel | string | 'Expand sidebar' / 'Collapse sidebar' | Accessible labels for each state. |
Accessibility
- The root is a named navigation landmark; each group is a list named by its heading.
- Collapsed mode hides labels visually only, so every item keeps its accessible name; a title shows the label on hover.
- The toggle reports aria-expanded and controls the sidebar; collapsible groups are disclosure buttons with aria-expanded.
- The active item is not conveyed by colour alone: it has aria-current and, in high contrast, an outline.
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves through items, group headings and the toggle. |
| Enter Space | Follows an item or toggles a group / the sidebar. |
Usage guidelines
Do
- Give every item an icon if the sidebar can collapse.
- Persist the collapsed state per user.
Don’t
- Put more than about ten items in one group.
- Hide primary destinations inside collapsed groups by default.