Sidebar

The left rail of an agent workbench. The panel is the seam well at app scale — a recessed muted surface — and the active row rises out of it as an embossed key. ⌘B collapses it to an icon rail.

Content
tsx
import { Inbox, Search, Settings } from "lucide-react"

import { Button } from "@/registry/seam/ui/button"
import {
  Sidebar,
  SidebarContent,
  SidebarFooter,
  SidebarGroup,
  SidebarGroupLabel,
  SidebarHeader,
  SidebarLabel,
  SidebarProvider,
  SidebarTrigger,
} from "@/registry/seam/ui/sidebar"

const ITEMS = [
  { icon: Inbox, label: "Inbox" },
  { icon: Search, label: "Search" },
  { icon: Settings, label: "Settings" },
]

export default function SidebarDemo() {
  return (
    <SidebarProvider className="bg-background h-72 overflow-hidden rounded-lg border">
      <Sidebar>
        <SidebarHeader>
          <SidebarTrigger />
          <SidebarLabel className="text-sm font-semibold">acme</SidebarLabel>
        </SidebarHeader>
        <SidebarContent>
          <SidebarGroup>
            <SidebarGroupLabel>Workspace</SidebarGroupLabel>
            {ITEMS.map(({ icon: Icon, label }) => (
              <Button
                key={label}
                variant="ghost"
                className="h-8 w-full justify-start gap-2.5 px-2.5 font-normal"
              >
                <Icon className="size-4 shrink-0" />
                <SidebarLabel className="flex-1 text-left">
                  {label}
                </SidebarLabel>
              </Button>
            ))}
          </SidebarGroup>
        </SidebarContent>
        <SidebarFooter>
          <SidebarLabel className="text-muted-foreground text-xs">
            ⌘B toggles the rail
          </SidebarLabel>
        </SidebarFooter>
      </Sidebar>
      <div className="text-muted-foreground flex flex-1 items-center justify-center text-sm">
        Content
      </div>
    </SidebarProvider>
  )
}
bunx --bun @seamui/cli@latest add sidebar

Notes

  • Collapse animates width — a layout dimension that can't spring cleanly — with an eased CSS transition; labels fade on the same clock via SidebarLabel. Both are suppressed under reduced motion (motion-reduce:transition-none), so the rail jumps instead of lurching.
  • ⌘/Ctrl+B toggles from anywhere inside the provider (the Superset shortcut); SidebarTrigger is a real seamui Button with aria-expanded.
  • Status-grouping is composition, not configuration: one SidebarGroup per agent-status bucket, loudest first, with count on the group label.
  • The provider carries data-state="expanded" | "collapsed"; anything inside can style off group-data-[state=collapsed]/sidebar:*.

Press feedback, reduced motion, and haptics follow the global policy — see Motion and Haptics.