Components / AI interface
SidebarNav
Collapsible workspace and chat navigation with gliding hover states.
Install
npx shadcn@latest add https://irisui.dev/r/sidebar-nav.jsonimport SidebarNav from "@/components/iris/sidebar-nav/sidebar-nav";
Preview
SidebarNav
A collapsible app sidebar with a workspace switcher, primary navigation, searchable chat history and a footer call-to-action, all sharing a gliding hover highlight.
When to use
- Use it as the left rail of an assistant or agent workspace that lists recent chats.
- Use it when the rail needs to collapse to 52px icons while keeping icon alignment.
- Not for marketing or site navigation — use
SiteHeader. Not for a hierarchical file tree — useTreeView.
Usage
import SidebarNav from "@/components/iris/sidebar-nav/sidebar-nav";
h(
"div",
{ style: { height: "100vh", display: "flex" } },
h(SidebarNav, {
fill: true,
recents: [
{ id: "workload", label: "Desk workload summary" },
{ id: "ferry", label: "Ferry strike quick brief", prompt: "Draft a quick brief on the ferry strike" },
],
activeTitle: "Desk workload summary",
onPick: (id, label, prompt) => openChat(id),
onNewChat: () => startChat(),
footerLabel: "Upgrade",
}),
);
Props
| Prop | Type | Default | Description |
|---|---|---|---|
recents |
{ id: string; label: string; prompt?: string }[] |
8 demo chats | Chat history rows, filtered by the built-in chat search. |
activeTitle |
string | null |
internal demo state | Controlled selected chat, matched by label. Leave it undefined for internal selection. |
onPick |
(id, label, prompt?) => void |
— | Called when a chat row is clicked. |
onNewChat |
() => void |
— | Called by "New chat" (and by the footer button when onFooterClick is not set). |
activeNav |
string |
internal | Controlled primary-nav key ("home", "invite", or "chats" for none). |
onNavigate |
(key: string) => void |
— | Called when a primary-nav row is chosen. |
footerLabel / footerIcon / onFooterClick |
string / ReactNode / () => void |
"Upgrade" / — / — |
Footer call-to-action button. |
fill |
boolean |
false |
true uses the parent's full height. The default is a fixed 600px. |
className |
string |
"" |
Extra classes on the <aside>. |
variant |
string |
— | Accepted for gallery parity. It has no effect. |
Notes
- The workspace name ("Aegean evening desk", an ErmisAI newsroom), its newspaper icon and the "Invite members 3/5" row are hard-coded, as is the workspace switcher menu. Long workspace names truncate with an ellipsis.
- Icons come from
lucide-react. - Collapsing sets
data-sidebar-collapsedon the<aside>; rows narrow to 36px and their text fades out with a small leftward shift, so every icon stays centred in the 52px rail. - The
<aside>is labelled "Workspace navigation". The collapse and expand controls havearia-labels and are removed from the tab order while hidden. Chat search opens from the magnifier, and Escape closes it. - The sidebar has no background of its own. It sits on whatever surface you place it on (the preview uses
--canvas). - Width animates between 224px and 52px. The bundle's global reduced-motion rule shortens this to near zero.
- Reads
--hover-2,--field,--line,--line-strong,--ink,--ink-2and--ink-3.