Sidebar

A composable, themeable and customizable sidebar component.

Usage

import { ChevronDown, ChevronRight, Folder, FileText, Users, Mail, Bell } from "lucide-react"
import { useState } from "react"

const collapsibleItems = [
  {
    title: "Documents",
    icon: Folder,
    items: [
      { title: "Reports", url: "#", icon: FileText },
      { title: "Invoices", url: "#", icon: FileText },
      { title: "Contracts", url: "#", icon: FileText },
    ],
  },
  {
    title: "Team",
    icon: Users,
    items: [
      { title: "Members", url: "#", icon: Users },
      { title: "Roles", url: "#", icon: Users },
      { title: "Permissions", url: "#", icon: Users },
    ],
  },
  {
    title: "Communication",
    icon: Mail,
    items: [
      { title: "Messages", url: "#", icon: Mail },
      { title: "Notifications", url: "#", icon: Bell },
      { title: "Announcements", url: "#", icon: Bell },
    ],
  },
]

function CollapsibleMenuItem({ item }) {
  const [isOpen, setIsOpen] = useState(false)
  
  return (
    <>
      <SidebarMenuItem>
        <SidebarMenuButton onClick={() => setIsOpen(!isOpen)} className="pl-lg">
          <item.icon />
          <span>{item.title}</span>
          {isOpen ? <ChevronDown className="ml-auto" /> : <ChevronRight className="ml-auto" />}
        </SidebarMenuButton>
        {isOpen && (
          <SidebarMenuSub>
            {item.items.map((subItem) => (
              <SidebarMenuSubItem key={subItem.title}>
                <SidebarMenuSubButton asChild>
                  <a href={subItem.url}>
                    <subItem.icon />
                    <span>{subItem.title}</span>
                  </a>
                </SidebarMenuSubButton>
              </SidebarMenuSubItem>
            ))}
          </SidebarMenuSub>
        )}
      </SidebarMenuItem>
      <SidebarSeparator />
    </>
  )
}

<SidebarProvider>
  <Sidebar collapsible="offcanvas" className="relative">
    <SidebarHeader>
      <DropdownMenu className="w-full">
        <DropdownMenuTrigger asChild>
          <div className="flex items-center gap-md">
            <Avatar>
              <AvatarImage
                src="https://github.com/shadcn.png"
                alt="Team Avatar"
              />
              <AvatarFallback>GT</AvatarFallback>
            </Avatar>
            <div className="flex items-center gap-sm">
              Ge's Team
              <ChevronDown size={16} />
            </div>
          </div>
        </DropdownMenuTrigger>
        <DropdownMenuContent className="w-[var(--radix-dropdown-menu-trigger-width)]">
          <DropdownMenuItem>
            <span>Menu item1</span>
          </DropdownMenuItem>
          <DropdownMenuItem>
            <span>Menu item2</span>
          </DropdownMenuItem>
          <DropdownMenuItem>
            <span>Menu item3</span>
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>
    </SidebarHeader>
    <SidebarContent>
      <SidebarGroup>
        <SidebarInput placeholder="Search for anything" />
        <SidebarGroupContent>
          <SidebarMenu>
            {collapsibleItems.map((item) => (
              <CollapsibleMenuItem key={item.title} item={item} />
            ))}
            <SidebarMenuItem>
              <SidebarMenuSubButton asChild>
                <div>SidebarMenuAction</div>
              </SidebarMenuSubButton>
              <DropdownMenu>
                <DropdownMenuTrigger asChild>
                  <SidebarMenuAction>
                    <MoreHorizontal />
                  </SidebarMenuAction>
                </DropdownMenuTrigger>
                <DropdownMenuContent side="right" align="start">
                  <DropdownMenuItem>
                    <span>Edit Project</span>
                  </DropdownMenuItem>
                  <DropdownMenuItem>
                    <span>Delete Project</span>
                  </DropdownMenuItem>
                </DropdownMenuContent>
              </DropdownMenu>
            </SidebarMenuItem>
            <SidebarMenuItem className="group-data-[collapsible=icon]:hidden">
              <SidebarMenuSubButton>
                <div>SidebarMenuBadge</div>
              </SidebarMenuSubButton>
              <SidebarMenuBadge>24</SidebarMenuBadge>
            </SidebarMenuItem>
          </SidebarMenu>
        </SidebarGroupContent>
      </SidebarGroup>
    </SidebarContent>
    <SidebarRail />
  </Sidebar>
  <SidebarTrigger />
</SidebarProvider>