Skip to Content
ComponentsSidebar

Sidebar

Primary navigation menu for left side of the page that includes support for branding, links, etc.

Documentation

Usage

import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Nav, NavAccountItem, NavBody, NavFooter, NavItem, NavList, Sidebar, SidebarToggle, } from "@optiaxiom/react"; import { IconBinaryTree, IconChartLine, IconExternalLink, IconFlag2, IconLayoutSidebar, IconSettings, IconVocabulary, } from "@tabler/icons-react"; import { Canvas } from "../Canvas"; export function App() { return ( <Canvas> <Sidebar defaultExpanded> <Nav> <NavBody> <NavList> <NavItem icon={<IconBinaryTree />}>Projects</NavItem> <NavItem active icon={<IconFlag2 />}> Flags </NavItem> <NavItem icon={<IconChartLine />}>Events</NavItem> <NavItem icon={<IconSettings />}>Settings</NavItem> <NavItem addonAfter={<IconExternalLink size="16" />} asChild icon={<IconVocabulary />} > <a href="/">Tutorial</a> </NavItem> </NavList> </NavBody> <NavFooter> <NavList> <SidebarToggle icon={<IconLayoutSidebar />} /> <DropdownMenu> <DropdownMenuTrigger asChild> <NavAccountItem name="Rhaenyra Targaryen" organization="Optimizely" src="https://i.pravatar.cc/150?img=10" /> </DropdownMenuTrigger> <DropdownMenuContent align="end" side="right"> <DropdownMenuItem>View Profile</DropdownMenuItem> <DropdownMenuItem>Settings</DropdownMenuItem> <DropdownMenuItem>Logout</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </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 { Panel } from "../../Panel"; export function App() { return ( <Canvas size="sm"> <Sidebar expanded> <Nav> <Panel 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 } from "@optiaxiom/react"; import { SubNav } from "@optiaxiom/react/unstable"; import { Canvas } from "../../Canvas"; import { Panel } from "../../Panel"; export function App() { return ( <Canvas size="sm"> <Sidebar> <Nav /> <SubNav> <Panel 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 { Panel } from "../../Panel"; export function App() { return ( <Canvas> <Sidebar expanded> <Nav> <NavHeader> <Panel description="A sticky header that is always visible at the top of the panel." title="NavHeader" /> </NavHeader> <NavBody> <Panel description="The main navigation body that is scrollable and should contain all your navigation items." title="NavBody" /> </NavBody> <NavFooter> <Panel 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 } from "@optiaxiom/react"; import { SubNav } from "@optiaxiom/react/unstable"; import { Canvas } from "../../Canvas"; import { Panel } from "../../Panel"; export function App() { return ( <Canvas> <Sidebar> <Nav /> <SubNav> <NavHeader> <Panel description="A sticky header that is always visible at the top of the panel." title="NavHeader" /> </NavHeader> <NavBody> <Panel description="The main navigation body that is scrollable and should contain all your navigation items." title="NavBody" /> </NavBody> <NavFooter> <Panel 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.

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 { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Nav, NavAccountItem, NavFooter, NavList, Sidebar, } from "@optiaxiom/react"; import { Canvas } from "../../Canvas"; export function App() { return ( <Canvas size="auto"> <Sidebar expanded> <Nav> <NavFooter> <NavList> <DropdownMenu> <DropdownMenuTrigger asChild> <NavAccountItem name="Rhaenyra Targaryen" organization="Optimizely" src="https://i.pravatar.cc/150?img=10" /> </DropdownMenuTrigger> <DropdownMenuContent align="end" side="right"> <DropdownMenuItem>View Profile</DropdownMenuItem> <DropdownMenuItem>Settings</DropdownMenuItem> <DropdownMenuItem>Logout</DropdownMenuItem> </DropdownMenuContent> </DropdownMenu> </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 collapsible section.

import { Nav, NavBody, NavItem, NavList, Sidebar } from "@optiaxiom/react"; import { NavGroup, NavGroupContent, NavGroupTrigger, } from "@optiaxiom/react/unstable"; 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 defaultOpen> <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, NavItem, NavList, Sidebar } from "@optiaxiom/react"; import { NavGroup, NavGroupContent, NavGroupTrigger, NavSeparator, } from "@optiaxiom/react/unstable"; 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 defaultOpen> <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

import { NavBody, NavItem, NavList, Sidebar } from "@optiaxiom/react"; import { NavGroup, NavGroupContent, NavGroupTrigger, NavSeparator, SubNav, } from "@optiaxiom/react/unstable"; 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 defaultOpen> <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 defaultOpen> <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

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

defaultExpanded

The initial expanded state in uncontrolled mode.

false | true

expanded

The expanded state in controlled mode.

false | true

onExpandedChange

Handler that is called when the expanded state changes.

(expanded: boolean) => void

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

active

false | true

addonAfter

Display content inside the button after children.

ReactNode

aria-label

string

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

icon

Display an icon before button content.

ReactNode

Nav

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

defaultExpanded

false | true

expanded

false | true

onExpandedChange

(expanded: boolean) => void

SubNav

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

NavHeader

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

NavBody

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

NavList

Supports all Box props in addition to its own. Renders a <ul> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

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

active

false | true

addonAfter

Display content inside the button after children.

ReactNode

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

icon

Display an icon before button content.

ReactNode

NavGroup

Supports all Disclosure props in addition to its own. Renders an <li> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

defaultOpen

The initial open state in uncontrolled mode.

false | true

disabled

false | true

onOpenChange

Handler that is called when the open state changes.

(open: boolean) => void

open

The open state in controlled mode.

false | true

NavGroupTrigger

Supports all DisclosureTrigger props in addition to its own. Renders a <div> element.

Prop

addonAfter

ReactNode

addonBefore

ReactNode

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

chevronPosition

"end" | "start"

className

string

NavGroupContent

Supports all DisclosureContent props in addition to its own. Renders a <ul> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

NavSeparator

Supports all Separator props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

decorative

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

false | true

orientation

ResponsiveValue<"horizontal" | "vertical">

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

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

name

string

organization

string

src

string

NavFooter

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

Changelog

0.12.1

  • Added SubNav component

0.4.0

  • Added component
Last updated on