Clidey UXDocs

Sidebar

Sidebar is a comprehensive navigation sidebar component with collapsible menus, submenus, mobile responsiveness, and multiple layout variants. It's built on a context provider and exposes a useSidebar hook for programmatic control.

Interactive example#

Sidebar · Live example

Overview

The surrounding content stays in place.

Use the embedded sidebar to switch sections or collapse it to an icon rail.

The code uses shared demo presentation helpers. Their complete source and styling are included in the LLM build context.

Import#

TSX

import {
  SidebarProvider,
  Sidebar,
  SidebarContent,
  SidebarHeader,
  SidebarFooter,
  SidebarGroup,
  SidebarGroupLabel,
  SidebarGroupContent,
  SidebarMenu,
  SidebarMenuItem,
  SidebarMenuButton,
  SidebarMenuBadge,
  SidebarMenuSub,
  SidebarMenuSubItem,
  SidebarMenuSubButton,
  SidebarTrigger,
  SidebarInset,
  SidebarSeparator,
  useSidebar,
} from '@clidey/ux';

Setup#

Wrap your layout with SidebarProvider:

TSX

<SidebarProvider>
  <AppSidebar />
  <SidebarInset>
    <main>{/* page content */}</main>
  </SidebarInset>
</SidebarProvider>

Basic sidebar#

TSX

function AppSidebar() {
  const navItems = [
    { title: 'Dashboard', icon: LayoutDashboard, href: '/' },
    { title: 'Projects', icon: FolderOpen, href: '/projects' },
    { title: 'Team', icon: Users, href: '/team' },
    { title: 'Settings', icon: Settings, href: '/settings' },
  ];

  return (
    <Sidebar>
      <SidebarHeader>
        <div className="px-2 py-1.5 font-semibold">My App</div>
      </SidebarHeader>
      <SidebarContent>
        <SidebarGroup>
          <SidebarGroupLabel>Navigation</SidebarGroupLabel>
          <SidebarGroupContent>
            <SidebarMenu>
              {navItems.map((item) => (
                <SidebarMenuItem key={item.title}>
                  <SidebarMenuButton>
                    <a href={item.href}>
                      <item.icon />
                      <span>{item.title}</span>
                    </a>
                  </SidebarMenuButton>
                </SidebarMenuItem>
              ))}
            </SidebarMenu>
          </SidebarGroupContent>
        </SidebarGroup>
      </SidebarContent>
      <SidebarFooter>
        <SidebarMenu>
          <SidebarMenuItem>
            <SidebarMenuButton>
              <a href="/logout">
                <LogOut />
                <span>Log out</span>
              </a>
            </SidebarMenuButton>
          </SidebarMenuItem>
        </SidebarMenu>
      </SidebarFooter>
    </Sidebar>
  );
}

With sub-menus#

TSX

<SidebarMenuItem>
  <SidebarMenuButton>
    <FileText />
    <span>Documents</span>
  </SidebarMenuButton>
  <SidebarMenuSub>
    <SidebarMenuSubItem>
      <SidebarMenuSubButton>
        <a href="/docs/reports">Reports</a>
      </SidebarMenuSubButton>
    </SidebarMenuSubItem>
    <SidebarMenuSubItem>
      <SidebarMenuSubButton>
        <a href="/docs/invoices">Invoices</a>
      </SidebarMenuSubButton>
    </SidebarMenuSubItem>
  </SidebarMenuSub>
</SidebarMenuItem>

With badge#

TSX

<SidebarMenuButton>
  <Bell />
  <span>Notifications</span>
  <SidebarMenuBadge>12</SidebarMenuBadge>
</SidebarMenuButton>

TSX

{/* Default: full-width sidebar */}
<Sidebar variant="sidebar">

{/* Floating: detached with shadow */}
<Sidebar variant="floating">

{/* Inset: content is inset from edges */}
<Sidebar variant="inset">

Collapsible behavior#

TSX

{/* Slides off-canvas when collapsed (default) */}
<Sidebar collapsible="offcanvas">

{/* Collapses to icon-only mode */}
<Sidebar collapsible="icon">

{/* Never collapses */}
<Sidebar collapsible="none">

Toggle button#

Add SidebarTrigger to the page header to give users a collapse/expand button:

TSX

<header className="flex items-center gap-2 p-4 border-b">
  <SidebarTrigger />
  <h1>Page Title</h1>
</header>

useSidebar hook#

TSX

function SidebarControl() {
  const { open, setOpen, toggleSidebar, isMobile, state } = useSidebar();

  return (
    <button onClick={toggleSidebar}>
      {state === 'expanded' ? 'Collapse' : 'Expand'}
    </button>
  );
}

Hook return values

ValueTypeDescription
state"expanded" | "collapsed"Current sidebar state.
openbooleanWhether the sidebar is open.
setOpen(open: boolean) => voidProgrammatically open or close.
isMobilebooleanWhether the viewport is mobile-sized.
openMobilebooleanMobile sheet open state.
setOpenMobile(open: boolean) => voidControl mobile sheet.
toggleSidebar() => voidToggle between expanded and collapsed.

SidebarProvider Props#

PropTypeDefaultDescription
defaultOpenbooleantrueInitial open state.
openboolean—Controlled open state.
onOpenChange(open: boolean) => void—Called when open state changes.
PropTypeDefaultDescription
side"left" | "right""left"Which side the sidebar appears on.
variant"sidebar" | "floating" | "inset" | "embed""sidebar"Visual style variant.
collapsible"offcanvas" | "icon" | "none""offcanvas"Collapse behavior.

SidebarMenuButton Props#

PropTypeDefaultDescription
variant"default" | "outline""default"Visual style.
size"default" | "sm" | "lg""default"Button size.
isActivebooleanfalseHighlights the button as the current page.
asChildbooleanfalseRender as the child element (e.g., <a>).
tooltipstring | TooltipContent—Tooltip shown in icon-only collapsed mode.

Was this page helpful?