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
#
App.tsx
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.
|
className
|
defaultExpanded The initial expanded state in uncontrolled mode.
|
expanded The expanded state in controlled mode.
|
onExpandedChange Handler 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 |
---|
active
|
addonAfter Display content inside the button after
|
aria-label
|
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.
|
className
|
icon Display an icon before button content.
|
#
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.
|
className
|
defaultExpanded
|
expanded
|
onExpandedChange
|
#
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.
|
className
|
#
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.
|
className
|
#
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.
|
className
|
#
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.
|
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 |
---|
active
|
addonAfter Display content inside the button after
|
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.
|
className
|
icon Display an icon before button content.
|
#
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.
|
className
|
defaultOpen The initial open state in uncontrolled mode.
|
disabled
|
onOpenChange Handler that is called when the open state changes.
|
open The open state in controlled mode.
|
#
NavGroupTrigger
#
Supports all DisclosureTrigger props in addition to its own. Renders a <div>
element.
Prop |
---|
addonAfter
|
addonBefore
|
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.
|
chevronPosition
|
className
|
#
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.
|
className
|
#
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.
|
className
|
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.
|
orientation
|
#
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.
|
className
|
name
|
organization
|
src
|
#
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.
|
className
|
#
Changelog
#
#
0.12.1
#
- Added
SubNav
component
#
0.4.0
#
- Added component