Tempa UI

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

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.