Navigation · astro-ui · SidebarNew
Sidebar
Side navigation shell with header, grouped links, and a footer.
Sidebar is a <nav> landmark with three regions: a header for the product or workspace switcher, a scrollable body of SidebarGroup and SidebarItem children, and a footer for the user menu. Groups can be static or collapsible through native <details>, so a long navigation tree expands and collapses without any JavaScript. Collapsing the whole sidebar to an icon rail is application state, not a visual variant, and is left to the app.
Features
- Attached (flush) or floating (stand-off) surfaces
- Optional sticky positioning and a scrollable body
- SidebarGroup: static groups or native `<details>` disclosures
- SidebarItem: links or action buttons, icons, badges, nested indent
- `active` maps to `aria-current="page"` on links and buttons, not a class
- Header and footer slots for brand and user menus
Usage
---
import { Sidebar, SidebarGroup, SidebarItem } from "astro-ui";
---
<Sidebar ariaLabel="Project">
<div slot="header">Acme</div>
<SidebarGroup label="Workspace">
<SidebarItem href="/overview" active>Overview</SidebarItem>
<SidebarItem href="/deploys" badge="3">Deploys</SidebarItem>
</SidebarGroup>
<div slot="footer">ada@acme.dev</div>
</Sidebar>Demos
Workspace sidebar
<Sidebar ariaLabel="Project" sticky>
<div slot="header">
<Avatar size="sm">AC</Avatar>
<span>Acme Inc.</span>
</div>
<SidebarGroup label="Workspace">
<SidebarItem href="#overview" active>
<span slot="icon" aria-hidden="true">◎</span>
Overview
</SidebarItem>
<SidebarItem href="#deploys" badge="3">
<span slot="icon" aria-hidden="true">⇡</span>
Deploys
</SidebarItem>
<SidebarItem href="#settings">
<span slot="icon" aria-hidden="true">⚙</span>
Settings
</SidebarItem>
</SidebarGroup>
<div slot="footer">ada@acme.dev</div>
</Sidebar>Collapsible groups
<Sidebar ariaLabel="Docs">
<SidebarGroup label="Getting started" collapsible open>
<SidebarItem href="#install">Install</SidebarItem>
<SidebarItem href="#tokens">Tokens</SidebarItem>
</SidebarGroup>
<SidebarGroup label="Components" collapsible>
<SidebarItem href="#button">Button</SidebarItem>
<SidebarItem href="#menu">Menu</SidebarItem>
</SidebarGroup>
</Sidebar>Client-routed action rows
<Sidebar ariaLabel="Views">
<SidebarGroup label="Views">
<SidebarItem active>
<span slot="icon" aria-hidden="true">◎</span>
Overview
</SidebarItem>
<SidebarItem>
<span slot="icon" aria-hidden="true">☰</span>
Members
</SidebarItem>
<SidebarItem disabled>Billing (soon)</SidebarItem>
</SidebarGroup>
</Sidebar>Without an href, SidebarItem renders a real button — use it for client-routed views. active still exposes aria-current="page".
Floating with nested items
<Sidebar variant="floating" ariaLabel="Files">
<div slot="header">Files</div>
<SidebarGroup label="Source">
<SidebarItem href="#src">src</SidebarItem>
<SidebarItem href="#components" nested>components</SidebarItem>
<SidebarItem href="#styles" nested>styles</SidebarItem>
<SidebarItem href="#locked" disabled>archive (read-only)</SidebarItem>
</SidebarGroup>
</Sidebar>API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "attached" | "floating" | "attached" | Surface treatment. |
sticky | boolean | false | Stick to the viewport while content scrolls. |
ariaLabel | string | "Sidebar" | Accessible name for the navigation landmark. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Element id. |
ariaLabel | string | — | Accessible name. |
Slots
| Slot | Description |
|---|---|
header | Brand or workspace switcher. |
(default) | SidebarGroup and SidebarItem children. |
footer | User menu or account row. |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Root is a
<nav>landmark named byariaLabel - Groups use
role="group"witharia-labelledby, or<summary>when collapsible - Current page is exposed with
aria-current="page"in both link and button rows - Disabled items use
aria-disabledand drop theirhref - Collapsible groups are native
<details>— no keyboard handler to get wrong
FAQ
How do I build the mobile drawer version?
Render the same groups inside `Sheet side="left"` and trigger it from a Navbar button. The sidebar itself stays hidden below your breakpoint; `Sheet` already owns the dialog focus trap.
Can I collapse it to an icon rail?
Not as a prop. Rail/collapsed state is application state: hide the labels yourself (a `data-collapsed` attribute on the nav plus your own CSS), and keep the accessible name on each item so the rail stays usable.
What props does SidebarItem take?
`href`, `active`, `disabled`, `badge`, `nested`, `class`, `id`, plus an `icon` slot. `active` renders `aria-current="page"` on links and buttons alike.
When do I use a button row instead of a link?
When navigation happens client-side (a view switcher, a filter, a drawer toggle). Omit `href` and SidebarItem renders `<button type="button">`, so keyboard activation and form-less behavior stay native.
Changelog
Version history mentioning Sidebar.
- Navigation (7): Tabs, Breadcrumb, Pagination, Stepper, Tree, Navbar, Sidebar.