Sidebar

Collapsible app sidebar with groups, menus, badges and a rail, in sidebar, floating and inset layouts, that becomes a sheet on small screens.

Installation

pnpm dlx shadcn@latest add @ward/sidebar

Add the Ward registry to components.json once:

"registries": {
  "@ward": "https://ward.so/r/{name}.json"
}

Or install from the URL with no configuration: npx shadcn@latest add https://ward.so/r/sidebar.json

Usage

import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
import { FolderIcon, InboxIcon, SettingsIcon } from "lucide-react";
<SidebarProvider>
  <Sidebar collapsible="icon">
    <SidebarHeader>Ward</SidebarHeader>
    <SidebarContent>
      <SidebarGroup>
        <SidebarGroupLabel>Manage</SidebarGroupLabel>
        <SidebarGroupContent>
          <SidebarMenu>
            <SidebarMenuItem>
              <SidebarMenuButton asChild isActive tooltip="Inbox"><a href="/inbox"><InboxIcon />Inbox</a></SidebarMenuButton>
              <SidebarMenuBadge>12</SidebarMenuBadge>
            </SidebarMenuItem>
            <SidebarMenuItem>
              <SidebarMenuButton asChild tooltip="Collections"><a href="/collections"><FolderIcon />Collections</a></SidebarMenuButton>
            </SidebarMenuItem>
          </SidebarMenu>
        </SidebarGroupContent>
      </SidebarGroup>
    </SidebarContent>
    <SidebarFooter>
      <SidebarMenu>
        <SidebarMenuItem>
          <SidebarMenuButton asChild tooltip="Settings"><a href="/settings"><SettingsIcon />Settings</a></SidebarMenuButton>
        </SidebarMenuItem>
      </SidebarMenu>
    </SidebarFooter>
  </Sidebar>
  <SidebarInset>
    <header className="flex h-12 items-center px-3"><SidebarTrigger /></header>
    {children}
  </SidebarInset>
</SidebarProvider>

Props

PropTypeDefaultDescription
SidebarProvider defaultOpenbooleantrueWhether the sidebar starts expanded when it is uncontrolled.
SidebarProvider openboolean-Whether the sidebar is expanded, when the parent controls it; pair it with onOpenChange.
SidebarProvider onOpenChange(open: boolean) => void-Called when the sidebar expands or collapses. Toggling also saves the choice in the sidebar_state cookie, and Ctrl or Cmd with B toggles it.
SidebarProvider classNamestring-The wrapper is at least one screen tall (min-h-svh), so add min-h-0 to fit it inside a box of a fixed height.
Sidebar side"left" | "right""left"Edge of the layout the sidebar sits on.
Sidebar variant"sidebar" | "floating" | "inset""sidebar"Flush with a border, floating with a gap and rounded corners, or inset with the page shown as a rounded panel; inset needs SidebarInset.
Sidebar collapsible"offcanvas" | "icon" | "none""offcanvas"Slide out of view, shrink to an icon rail, or never collapse. Below 768px the sidebar opens as a sheet from SidebarTrigger instead.
SidebarMenuButton isActivebooleanfalseHighlight the button as the current page.
SidebarMenuButton asChildbooleanfalseUse the child element, such as a link, instead of rendering a button.
SidebarMenuButton tooltipstring | TooltipContent props-Label shown beside the button, only while the sidebar is collapsed to icons.
SidebarMenuButton variant"default" | "outline""default"Plain, or with a thin outline.
SidebarMenuButton size"default" | "sm" | "lg""default"Height of the button.
SidebarMenuSubButton size"sm" | "md""md"Text size of a link in a nested SidebarMenuSub.
SidebarMenuAction showOnHoverbooleanfalseHide the action until its menu item is hovered or focused.
SidebarMenuSkeleton showIconbooleanfalseShow a placeholder icon beside the placeholder text while a menu loads.
useSidebar(){ state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar }-Read and change the sidebar from any component inside SidebarProvider; state is "expanded" or "collapsed".

Ward · Version 1.0.0 · Registry manifest