Sidebar
Installation
Section titled “Installation”npx bambiui add sidebarImport the token file once from your global stylesheet:
@import "./styles/bambi.css";Then import the component:
import { Sidebar, SidebarHeader, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarMenuLink, SidebarRail,} from './components/ui/sidebar';<script> import Sidebar from './components/ui/Sidebar.svelte';</script><script setup>import Sidebar from './components/ui/Sidebar.vue';</script>---import Sidebar from './components/ui/Sidebar.astro';---API Styles
Section titled “API Styles”Use props/config-driven Sidebar props for common navigation. Use compound markup for advanced layouts, custom structure, or full control. Both styles render the same sidebar sections, groups, menus, items, and rail.
Props-driven Usage
Section titled “Props-driven Usage”<Sidebarheader={<span>My App</span>}footer={<button type="button">Log out</button>}groups={[ { label: "Navigation", items: [ { label: "Home", href: "/", active: true }, { label: "Settings", href: "/settings" }, ], },]}/>{#snippet header()}My App{/snippet}{#snippet footer()}<button type="button">Log out</button>{/snippet}
<Sidebar{header}{footer}groups={[ { label: "Navigation", items: [ { label: "Home", href: "/", active: true }, { label: "Settings", href: "/settings" }, ], },]}/><Sidebar:groups="[{ label: 'Navigation', items: [ { label: 'Home', href: '/', active: true }, { label: 'Settings', href: '/settings' }, ],}]"><template #header>My App</template><template #footer><button type="button">Log out</button></template></Sidebar><Sidebargroups={[{ label: "Navigation", items: [ { label: "Home", href: "/", active: true }, { label: "Settings", href: "/settings" }, ],}]}><span slot="header">My App</span><button slot="footer" type="button">Log out</button></Sidebar>Compound Usage
Section titled “Compound Usage”<Sidebar side="left" collapsible="offcanvas"><SidebarHeader> <span>My App</span></SidebarHeader><SidebarContent> <SidebarGroup> <SidebarGroupLabel>Navigation</SidebarGroupLabel> <SidebarMenu> <SidebarMenuItem> <SidebarMenuLink href="/" active>Home</SidebarMenuLink> </SidebarMenuItem> <SidebarMenuItem> <SidebarMenuLink href="/settings">Settings</SidebarMenuLink> </SidebarMenuItem> </SidebarMenu> </SidebarGroup></SidebarContent><SidebarFooter> <SidebarMenuButton>Log out</SidebarMenuButton></SidebarFooter><SidebarRail /></Sidebar><Sidebar side="left" collapsible="offcanvas"><div class="bambi-sidebar-header">My App</div><div class="bambi-sidebar-content"> <div class="bambi-sidebar-group"> <span class="bambi-sidebar-group-label">Navigation</span> <ul class="bambi-sidebar-menu"> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/" data-active aria-current="page">Home</a> </li> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/settings">Settings</a> </li> </ul> </div></div><div class="bambi-sidebar-footer"> <button class="bambi-sidebar-menu-button" type="button">Log out</button></div></Sidebar><Sidebar side="left" collapsible="offcanvas"><div class="bambi-sidebar-header">My App</div><div class="bambi-sidebar-content"> <div class="bambi-sidebar-group"> <span class="bambi-sidebar-group-label">Navigation</span> <ul class="bambi-sidebar-menu"> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/" data-active aria-current="page">Home</a> </li> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/settings">Settings</a> </li> </ul> </div></div><div class="bambi-sidebar-footer"> <button class="bambi-sidebar-menu-button" type="button">Log out</button></div></Sidebar><Sidebar side="left" collapsible="offcanvas"><div class="bambi-sidebar-header">My App</div><div class="bambi-sidebar-content"> <div class="bambi-sidebar-group"> <span class="bambi-sidebar-group-label">Navigation</span> <ul class="bambi-sidebar-menu"> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/" data-active aria-current="page">Home</a> </li> <li class="bambi-sidebar-menu-item"> <a class="bambi-sidebar-menu-button" href="/settings">Settings</a> </li> </ul> </div></div><div class="bambi-sidebar-footer"> <button class="bambi-sidebar-menu-button" type="button">Log out</button></div></Sidebar>Collapsible Modes
Section titled “Collapsible Modes”| Mode | Behavior |
|---|---|
offcanvas | Slides off-screen; shows a backdrop overlay on mobile |
icon | Shrinks to icon-only width; text labels are hidden |
none | Always visible; no collapse behavior |
Controlled State
Section titled “Controlled State”const [open, setOpen] = useState(true);
<Sidebar open={open} onOpenChange={setOpen}>...</Sidebar><script>let open = $state(true);</script>
<Sidebar bind:open onOpenChange={(v) => (open = v)}>...</Sidebar><script setup>const open = ref(true);</script>
<Sidebar :open="open" @open-change="(v) => (open = v)">...</Sidebar><Sidebar default-open={false} collapsible="offcanvas">...</Sidebar>CSS Classes
Section titled “CSS Classes”Sub-part classes usable in any framework:
| Class | Element |
|---|---|
bambi-sidebar | Root nav element |
bambi-sidebar-header | Top header section |
bambi-sidebar-content | Scrollable main area |
bambi-sidebar-footer | Bottom footer section |
bambi-sidebar-group | Nav item group |
bambi-sidebar-group-label | Group heading text |
bambi-sidebar-menu | <ul> nav list |
bambi-sidebar-menu-item | <li> item wrapper |
bambi-sidebar-menu-button | Button/link nav item |
bambi-sidebar-overlay | Offcanvas backdrop |
bambi-sidebar-rail | Collapse toggle strip |
API Reference
Section titled “API Reference”Sidebar / <Sidebar>
Section titled “Sidebar / <Sidebar>”| Prop | Type | Default | Description |
|---|---|---|---|
side | 'left' | 'right' | 'left' | Which side the sidebar is on |
collapsible | 'icon' | 'offcanvas' | 'none' | 'offcanvas' | Collapse behavior |
defaultOpen | boolean | true | Initial open state (uncontrolled) |
open | boolean | — | Controlled open state |
onOpenChange | (open: boolean) => void | — | React/Svelte/Vue open state callback |
header | React node / Svelte snippet / Vue or Astro slot | — | Convenience header section |
footer | React node / Svelte snippet / Vue or Astro slot | — | Convenience footer section |
groups | Array<{ label?: string; items: SidebarItem[] }> | — | Config-driven grouped navigation |
items | SidebarItem[] | — | Config-driven ungrouped navigation |
SidebarItem supports label, href, active, disabled, optional React icon, and button-style onClick where the framework supports function props.
React-only sub-components
Section titled “React-only sub-components”SidebarHeader, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem all forward HTMLAttributes of their respective elements.
SidebarMenuButton adds active?: boolean and disabled?: boolean.
SidebarMenuLink (renders <a>) adds active?: boolean.
SidebarRail renders the collapse toggle button; reads open state from context.
Accessibility
Section titled “Accessibility”- The root element is
<nav aria-label="Sidebar navigation">— provides a landmark for screen readers. - The rail toggle button has
aria-label,aria-expanded, and is a real<button>element. - Active items should use
aria-current="page"(handled automatically bySidebarMenuLink/SidebarMenuButtonwhenactiveis set). - Disabled items use
data-disabledandaria-disabled;pointer-events: noneprevents interaction. - Tab order flows naturally through the sidebar; focus is not trapped in persistent mode.
- In offcanvas mode, the overlay dismisses the sidebar on click and when it is open the sidebar receives focus.