Sidebar
Primary navigation menu for left side of the page that includes support for branding, links, etc.
#
Documentation
#
#
Usage
#
"use client";
import {
Menu,
MenuContent,
MenuTrigger,
Nav,
NavAccountItem,
NavBody,
NavFooter,
NavItem,
NavList,
Sidebar,
SidebarToggle,
} from "@optiaxiom/react";
import {
IconBinaryTree,
IconChartLine,
IconExternalLink,
IconFlag2,
IconLayoutSidebar,
IconSettings,
IconVocabulary,
} from "@tabler/icons-react";
import { useState } from "react";
import { Canvas } from "../Canvas";
export function App() {
const [selected, setSelected] = useState("flags");
return (
<Canvas>
<Sidebar defaultExpanded>
<Nav>
<NavBody>
<NavList>
<NavItem
active={selected === "projects"}
icon={<IconBinaryTree />}
onClick={() => setSelected("projects")}
>
Projects
</NavItem>
<NavItem
active={selected === "flags"}
icon={<IconFlag2 />}
onClick={() => setSelected("flags")}
>
Flags
</NavItem>
<NavItem
active={selected === "events"}
icon={<IconChartLine />}
onClick={() => setSelected("events")}
>
Events
</NavItem>
<NavItem
active={selected === "settings"}
icon={<IconSettings />}
onClick={() => setSelected("settings")}
>
Settings
</NavItem>
<NavItem
addonAfter={<IconExternalLink size="16" />}
asChild
icon={<IconVocabulary />}
>
<a href="/">Tutorial</a>
</NavItem>
</NavList>
</NavBody>
<NavFooter>
<NavList>
<SidebarToggle icon={<IconLayoutSidebar />} />
<Menu
options={[
{ label: "View Profile" },
{ label: "Settings" },
{ label: "Logout" },
]}
>
<MenuTrigger asChild>
<NavAccountItem
name="Rhaenyra Targaryen"
organization="Optimizely"
src="https://i.pravatar.cc/150?img=10"
/>
</MenuTrigger>
<MenuContent align="end" side="right" />
</Menu>
</NavList>
</NavFooter>
</Nav>
</Sidebar>
</Canvas>
);
}#
Anatomy
#
import {
Nav,
NavAccountItem,
NavBody,
NavFooter,
NavHeader,
NavItem,
NavList,
Sidebar,
SidebarToggle,
} from "@optiaxiom/react";
import {
NavGroup,
NavGroupContent,
NavGroupTrigger,
NavSeparator,
SubNav,
} from "@optiaxiom/react/unstable";
export default () => (
<Sidebar>
<Nav>
<NavHeader />
<NavBody>
<NavList>
<NavItem />
<NavGroup>
<NavGroupTrigger />
<NavSeparator />
<NavGroupContent>
<NavItem />
</NavGroupContent>
</NavGroup>
</NavList>
</NavBody>
<NavFooter>
<NavList>
<SidebarToggle />
<NavItem />
<NavAccountItem />
</NavList>
</NavFooter>
</Nav>
<SubNav />
</Sidebar>
);#
Panels
#
The Nav component is used to create the primary navigation panel.
import { Nav, Sidebar } from "@optiaxiom/react";
import { Canvas } from "../../Canvas";
import { Note } from "../../Note";
export function App() {
return (
<Canvas size="sm">
<Sidebar expanded>
<Nav>
<Note description="The primary navigation panel." title="Nav" />
</Nav>
</Sidebar>
</Canvas>
);
}We can also create additional secondary navigation panels using the SubNav component. The rest of the hierarchy within SubNav is the exact same as Nav.
import { Nav, Sidebar, SubNav } from "@optiaxiom/react";
import { Canvas } from "../../Canvas";
import { Note } from "../../Note";
export function App() {
return (
<Canvas size="sm">
<Sidebar>
<Nav />
<SubNav>
<Note description="A secondary navigation panel." title="SubNav" />
</SubNav>
</Sidebar>
</Canvas>
);
}#
Sections
#
Each navigation panel contains three sections: header, body, and footer.
import { Nav, NavBody, NavFooter, NavHeader, Sidebar } from "@optiaxiom/react";
import { Canvas } from "../../Canvas";
import { Note } from "../../Note";
export function App() {
return (
<Canvas>
<Sidebar expanded>
<Nav>
<NavHeader>
<Note
description="A sticky header that is always visible at the top of the panel."
title="NavHeader"
/>
</NavHeader>
<NavBody>
<Note
description="The main navigation body that is scrollable and should contain all your navigation items."
title="NavBody"
/>
</NavBody>
<NavFooter>
<Note
description="A sticky footer that is always visible at the bottom of the panel."
title="NavFooter"
/>
</NavFooter>
</Nav>
</Sidebar>
</Canvas>
);
}Both primary and secondary navigation panels can contain these sections.
import {
Nav,
NavBody,
NavFooter,
NavHeader,
Sidebar,
SubNav,
} from "@optiaxiom/react";
import { Canvas } from "../../Canvas";
import { Note } from "../../Note";
export function App() {
return (
<Canvas>
<Sidebar>
<Nav />
<SubNav>
<NavHeader>
<Note
description="A sticky header that is always visible at the top of the panel."
title="NavHeader"
/>
</NavHeader>
<NavBody>
<Note
description="The main navigation body that is scrollable and should contain all your navigation items."
title="NavBody"
/>
</NavBody>
<NavFooter>
<Note
description="A sticky footer that is always visible at the bottom of the panel."
title="NavFooter"
/>
</NavFooter>
</SubNav>
</Sidebar>
</Canvas>
);
}#
Lists
#
Use NavList and NavItem to place navigation lists inside the body (or header/footer) navigation sections.
import { Nav, NavBody, NavItem, NavList, Sidebar } from "@optiaxiom/react";
import {
IconDashboard,
IconDeviceDesktop,
IconTestPipe,
} from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavItem icon={<IconDashboard />}>CMP</NavItem>
<NavItem icon={<IconDeviceDesktop />}>CMS</NavItem>
<NavItem icon={<IconTestPipe />}>Experimentation</NavItem>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Active items
#
Enable the active prop on NavItem to highlight the currently active/selected navigation item.
"use client";
import { Nav, NavBody, NavItem, NavList, Sidebar } from "@optiaxiom/react";
import {
IconDashboard,
IconDeviceDesktop,
IconTestPipe,
} from "@tabler/icons-react";
import { useState } from "react";
import { Canvas } from "../../Canvas";
export function App() {
const [selected, setSelected] = useState<string>("CMP");
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavItem
active={selected === "CMP"}
icon={<IconDashboard />}
onClick={() => setSelected("CMP")}
>
CMP
</NavItem>
<NavItem
active={selected === "CMS"}
icon={<IconDeviceDesktop />}
onClick={() => setSelected("CMS")}
>
CMS
</NavItem>
<NavItem
active={selected === "Experimentation"}
icon={<IconTestPipe />}
onClick={() => setSelected("Experimentation")}
>
Experimentation
</NavItem>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Items as links
#
Set asChild to true on NavItem and wrap children in an <a> element to render buttons as links.
import { Nav, NavBody, NavItem, NavList, Sidebar } from "@optiaxiom/react";
import { IconExternalLink, IconVocabulary } from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavItem
addonAfter={<IconExternalLink size="16" />}
asChild
icon={<IconVocabulary />}
>
<a href="/">Tutorial</a>
</NavItem>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Account items
#
Use NavAccountItem to include an account profile button within navigation lists.
import {
Menu,
MenuContent,
MenuTrigger,
Nav,
NavAccountItem,
NavFooter,
NavList,
Sidebar,
} from "@optiaxiom/react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavFooter>
<NavList>
<Menu
options={[
{ label: "View Profile" },
{ label: "Settings" },
{ label: "Logout" },
]}
>
<MenuTrigger asChild>
<NavAccountItem
name="Rhaenyra Targaryen"
organization="Optimizely"
src="https://i.pravatar.cc/150?img=10"
/>
</MenuTrigger>
<MenuContent align="end" side="right" />
</Menu>
</NavList>
</NavFooter>
</Nav>
</Sidebar>
</Canvas>
);
}#
Sidebar toggle
#
Use SidebarToggle to include a toggle button within navigation lists for collapsing/expanding the primary navigation panel.
Use the expanded and defaultExpanded props on Sidebar to toggle between controlled and uncontrolled usage. And combine it with onExpandedChange to listen for changes to the state.
import {
Nav,
NavFooter,
NavList,
Sidebar,
SidebarToggle,
} from "@optiaxiom/react";
import { IconLayoutSidebar } from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas>
<Sidebar defaultExpanded>
<Nav>
<NavFooter>
<NavList>
<SidebarToggle icon={<IconLayoutSidebar />} />
</NavList>
</NavFooter>
</Nav>
</Sidebar>
</Canvas>
);
}#
Groups
#
Use NavGroup, NavGroupTrigger, and NavGroupContent to group related navigation items together inside a section.
import {
Nav,
NavBody,
NavGroup,
NavGroupContent,
NavGroupTrigger,
NavItem,
NavList,
Sidebar,
} from "@optiaxiom/react";
import {
IconDashboard,
IconDeviceDesktop,
IconTestPipe,
} from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavGroup>
<NavGroupTrigger>Location</NavGroupTrigger>
<NavGroupContent>
<NavItem icon={<IconDashboard />}>CMP</NavItem>
<NavItem icon={<IconDeviceDesktop />}>CMS</NavItem>
<NavItem icon={<IconTestPipe />}>Experimentation</NavItem>
</NavGroupContent>
</NavGroup>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Collapsible groups
#
Use the collapsible prop on NavGroup to make the section collapsible. Use the defaultOpen/open/onOpenChange props if you want to control the collapsed/expanded state.
import {
Nav,
NavBody,
NavGroup,
NavGroupContent,
NavGroupTrigger,
NavItem,
NavList,
Sidebar,
} from "@optiaxiom/react";
import {
IconDashboard,
IconDeviceDesktop,
IconTestPipe,
} from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavGroup collapsible>
<NavGroupTrigger>Location</NavGroupTrigger>
<NavGroupContent>
<NavItem icon={<IconDashboard />}>CMP</NavItem>
<NavItem icon={<IconDeviceDesktop />}>CMS</NavItem>
<NavItem icon={<IconTestPipe />}>Experimentation</NavItem>
</NavGroupContent>
</NavGroup>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Group separators
#
Use NavSeparator inside NavGroup to add separators between navigation items or groups.
import {
Nav,
NavBody,
NavGroup,
NavGroupContent,
NavGroupTrigger,
NavItem,
NavList,
NavSeparator,
Sidebar,
} from "@optiaxiom/react";
import {
IconCopy,
IconDashboard,
IconDeviceDesktop,
IconRectangle,
IconTestPipe,
} from "@tabler/icons-react";
import { Canvas } from "../../Canvas";
export function App() {
return (
<Canvas size="auto">
<Sidebar expanded>
<Nav>
<NavBody>
<NavList>
<NavItem icon={<IconCopy />}>All</NavItem>
<NavItem icon={<IconRectangle />}>Recent</NavItem>
<NavGroup>
<NavSeparator />
<NavGroupTrigger>Location</NavGroupTrigger>
<NavGroupContent>
<NavItem icon={<IconDashboard />}>CMP</NavItem>
<NavItem icon={<IconDeviceDesktop />}>CMS</NavItem>
<NavItem icon={<IconTestPipe />}>Experimentation</NavItem>
</NavGroupContent>
</NavGroup>
</NavList>
</NavBody>
</Nav>
</Sidebar>
</Canvas>
);
}#
Secondary navigation
#
App.tsx
"use client";
import {
NavBody,
NavGroup,
NavGroupContent,
NavGroupTrigger,
NavItem,
NavList,
NavSeparator,
Sidebar,
SubNav,
} from "@optiaxiom/react";
import {
IconCopy,
IconDashboard,
IconDeviceDesktop,
IconRectangle,
IconReport,
IconStar,
IconTestPipe,
IconTrash,
} from "@tabler/icons-react";
import { useState } from "react";
import { Canvas } from "../Canvas";
import { PrimaryNav } from "./PrimaryNav";
export function App() {
const [selected, setSelected] = useState<string>("CMP");
return (
<Canvas>
<Sidebar>
<PrimaryNav />
<SubNav>
<NavBody>
<NavList>
<NavItem
active={selected === "All"}
icon={<IconCopy />}
onClick={() => setSelected("All")}
>
All
</NavItem>
<NavItem
active={selected === "Recent"}
icon={<IconRectangle />}
onClick={() => setSelected("Recent")}
>
Recent
</NavItem>
<NavItem
active={selected === "Favorites"}
icon={<IconStar />}
onClick={() => setSelected("Favorites")}
>
Favorites
</NavItem>
<NavItem
active={selected === "Trash"}
icon={<IconTrash />}
onClick={() => setSelected("Trash")}
>
Trash
</NavItem>
<NavGroup>
<NavSeparator />
<NavGroupTrigger>Location</NavGroupTrigger>
<NavGroupContent>
<NavItem
active={selected === "CMP"}
icon={<IconDashboard />}
onClick={() => setSelected("CMP")}
>
CMP
</NavItem>
<NavItem
active={selected === "CMS"}
icon={<IconDeviceDesktop />}
onClick={() => setSelected("CMS")}
>
CMS
</NavItem>
<NavItem
active={selected === "Experimentation"}
icon={<IconTestPipe />}
onClick={() => setSelected("Experimentation")}
>
Experimentation
</NavItem>
</NavGroupContent>
</NavGroup>
<NavGroup>
<NavSeparator />
<NavGroupTrigger>Analytics</NavGroupTrigger>
<NavGroupContent>
<NavItem
active={selected === "Dashboard"}
icon={<IconDashboard />}
onClick={() => setSelected("Dashboard")}
>
Dashboard
</NavItem>
<NavItem
active={selected === "Reports"}
icon={<IconReport />}
onClick={() => setSelected("Reports")}
>
Reports
</NavItem>
</NavGroupContent>
</NavGroup>
</NavList>
</NavBody>
</SubNav>
</Sidebar>
</Canvas>
);
}#
Props
#
#
Sidebar
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
defaultExpandedThe initial expanded state in uncontrolled mode.
Default: |
expandedThe expanded state in controlled mode.
|
onExpandedChangeHandler that is called when the expanded state changes.
|
#
SidebarToggle
#
Supports all Box props in addition to its own. Renders an <li> element element but forwards all props to an inner <button> element.
Prop |
|---|
activeWhether the nav item is currently active.
|
addonAfterDisplay content inside the button after
|
aria-label
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
iconDisplay an icon before button content.
|
#
Nav
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
defaultExpandedThe initial expanded state in uncontrolled mode.
|
expandedThe expanded state in controlled mode.
|
onExpandedChangeHandler that is called when the expanded state changes.
|
#
SubNav
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
NavHeader
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
NavBody
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
NavList
#
Supports all Box props in addition to its own. Renders a <ul> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
NavItem
#
Supports all Box props in addition to its own. Renders an <li> element element but forwards all props to an inner <button> element.
Prop |
|---|
activeWhether the nav item is currently active.
|
addonAfterDisplay content inside the button after
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
iconDisplay an icon before button content.
|
#
NavGroup
#
Supports all Disclosure props in addition to its own. Renders an <li> element element but forwards all props to an inner <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
collapsibleWhether the nav group should be collapsible or not.
|
defaultOpenThe initial open state in uncontrolled mode.
Default: |
disabled
|
onOpenChangeHandler that is called when the open state changes.
|
openThe open state in controlled mode.
|
#
NavGroupTrigger
#
Supports all DisclosureTrigger props in addition to its own. Renders a <div> element.
Prop |
|---|
addonAfterDisplay content after the button.
|
addonBeforeDisplay content before the button.
|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
chevronPositionControl which side to place the chevron.
|
className
|
#
NavGroupContent
#
Supports all DisclosureContent props in addition to its own. Renders a <ul> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
NavSeparator
#
Supports all Separator props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
decorativeWhether or not the component is purely decorative. When true, accessibility-related attributes are updated so that that the rendered element is removed from the accessibility tree.
|
orientationThe orientation of the separator.
|
#
NavAccountItem
#
Supports all Box props in addition to its own. Renders an <li> element element but forwards all props to an inner <button> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
nameThe name of the user.
|
organizationThe name of the current organization user belongs to.
|
srcRender the image inside the avatar.
|
#
NavFooter
#
Supports all Box props in addition to its own. Renders a <div> element.
Prop |
|---|
asChildChange the default rendered element for the one passed as a child, merging their props and behavior. Read the Composition guide for more details.
|
className
|
#
Changelog
#
#
1.4.5
#
- Added
collapsibleprop toNavGroupand set the default tofalse.
#
0.12.1
#
- Added
SubNavcomponent
#
0.4.0
#
- Added component