Sidebar
Vertical navigation sidebar with expand and collapse.
Code
components/Sidebar.astro
---interface SidebarItem { label: string; href: string;} interface Props { items: SidebarItem[]; variant?: "expanded" | "collapsed"; class?: string;} const { items, variant = "expanded", class: className = "",} = Astro.props;--- <aside class={`sidebar flex flex-col bg-black-onyx text-white-ghost h-full w-64 transition-all duration-300 ${variant === "collapsed" ? "active" : ""} ${className}`}> <div class="flex items-center justify-between px-4 py-4 border-b border-white-ghost/10"> <span class="sidebar-label text-sm font-medium">Navigation</span> <button id="sidebar-toggle-btn" class="p-1 rounded hover:bg-white-ghost/10 transition-colors" aria-label="Toggle sidebar" aria-expanded={variant === "collapsed" ? "false" : "true"} aria-controls="sidebar-nav"> <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"> <path d="M224,128a8,8,0,0,1-8,8H40a8,8,0,0,1,0-16H216A8,8,0,0,1,224,128ZM40,72H216a8,8,0,0,0,0-16H40a8,8,0,0,0,0,16ZM216,184H40a8,8,0,0,0,0,16H216a8,8,0,0,0,0-16Z"></path> </svg> </button> </div> <nav id="sidebar-nav" class="flex-1 py-4 overflow-y-auto"> <ul class="flex flex-col gap-1 px-2"> {items.map((item) => ( <li> <a href={item.href} class="flex items-center gap-3 px-3 py-2 rounded hover:bg-white-ghost/10 transition-colors" aria-label={item.label}> <svg aria-hidden="true" class="shrink-0" xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" viewBox="0 0 256 256"> <circle cx="128" cy="128" r="48"></circle> </svg> <span class="sidebar-label text-sm">{item.label}</span> </a> </li> ))} </ul> </nav></aside> <style> .sidebar.active { width: 64px; } .sidebar.active .sidebar-label { display: none; }</style> <script> document.querySelectorAll(".sidebar").forEach((sidebar) => { const toggleBtn = sidebar.querySelector("#sidebar-toggle-btn"); toggleBtn?.addEventListener("click", () => { const isActive = sidebar.classList.toggle("active"); toggleBtn.setAttribute("aria-expanded", !isActive); }); });</script>
Preview
Expanded
Collapsed
Usage
<Sidebar items={[ { label: "Dashboard", href: "#" }, { label: "Settings", href: "#" }, { label: "Profile", href: "#" }, ]}/>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| items | SidebarItem[] | — | Array of navigation items with label and href. |
| variant | "expanded" | "collapsed" | "expanded" | Sidebar display variant. |
| class | string | — | Additional CSS classes. |