Skip to main content

Starwind UI v1.16 is now available! With new popover and more components With new input-group, native-select, and popover components

Sidebar

Sidebars are one of the most complex components to build. They are central to any application and often contain a lot of moving parts.

The Starwind Sidebar is composable, themeable, and customizable.

Info

The Starwind Sidebar is extremely similar to the shadcn/ui sidebar component.

Installation

Add the following colors to your global CSS file (usually src/styles/starwind.css) if they do not already exist:

Info

They may not exist if you are adding the sidebar to an existing project. For new projects the starwind init command automatically adds this setup.

src/styles/starwind.css
@theme inline {
/* other variables... */
--color-sidebar: var(--sidebar-background);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-outline: var(--sidebar-outline);
}
:root {
/* other variables... */
/* sidebar variables */
--sidebar-background: var(--color-neutral-50);
--sidebar-foreground: var(--color-neutral-950);
--sidebar-primary: var(--color-blue-700);
--sidebar-primary-foreground: var(--color-neutral-50);
--sidebar-accent: var(--color-neutral-100);
--sidebar-accent-foreground: var(--color-neutral-900);
--sidebar-border: var(--color-neutral-200);
--sidebar-outline: var(--color-neutral-400);
}
.dark {
/* other variables... */
/* sidebars variables */
--sidebar-background: var(--color-neutral-900);
--sidebar-foreground: var(--color-neutral-50);
--sidebar-primary: var(--color-blue-700);
--sidebar-primary-foreground: var(--color-neutral-50);
--sidebar-accent: var(--color-neutral-800);
--sidebar-accent-foreground: var(--color-neutral-100);
--sidebar-border: var(--color-neutral-800);
--sidebar-outline: var(--color-neutral-600);
}

Structure

A Sidebar component is composed of the following parts:

  • SidebarProvider - Handles collapsible state and keyboard shortcuts
  • Sidebar - The sidebar container
  • SidebarHeader and SidebarFooter - Sticky at the top and bottom of the sidebar
  • SidebarContent - Scrollable content area
  • SidebarGroup - Section within the SidebarContent
  • SidebarTrigger - Button to toggle the sidebar
Sidebar Structure

Usage

Basic Layout

Wrap your application with SidebarProvider and place Sidebar alongside your main content:

---
import {
Sidebar,
SidebarContent,
SidebarProvider,
SidebarTrigger,
} from "@/components/starwind/sidebar";
import { AppSidebar } from "@/components/app-sidebar";
---
<SidebarProvider>
<AppSidebar />
<main>
<SidebarTrigger />
<slot />
</main>
</SidebarProvider>

Creating a Sidebar Component

---
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarHeader,
} from "@/components/starwind/sidebar";
---
<Sidebar>
<SidebarHeader />
<SidebarContent>
<SidebarGroup />
<SidebarGroup />
</SidebarContent>
<SidebarFooter />
</Sidebar>

With Menu Items

Use SidebarMenu, SidebarMenuItem, and SidebarMenuButton to create navigation menus:

With Inset Variant

When using the inset variant, wrap your main content in SidebarInset:

---
import {
Sidebar,
SidebarInset,
SidebarProvider,
} from "@/components/starwind/sidebar";
---
<SidebarProvider>
<Sidebar variant="inset">
{/* Sidebar content */}
</Sidebar>
<SidebarInset>
<main>{/* Main content */}</main>
</SidebarInset>
</SidebarProvider>

API Reference

SidebarProvider

The root component that provides sidebar state and handles keyboard shortcuts.

PropTypeDefault
defaultOpenbooleantrue
keyboardShortcutstring"b"
classstring-
<SidebarProvider defaultOpen={true} keyboardShortcut="b">
{/* Sidebar and content */}
</SidebarProvider>

Additional Notes:

  • defaultOpen: Controls whether the sidebar starts expanded or collapsed
  • keyboardShortcut: The key used with Cmd (Mac) or Ctrl (Windows) to toggle the sidebar

Width

Control the sidebar width using CSS variables on SidebarProvider:

<SidebarProvider
style={{
"--sidebar-width": "20rem",
"--sidebar-width-icon": "4rem",
}}
>
<Sidebar />
</SidebarProvider>
VariableDefaultDescription
--sidebar-width18remWidth of the expanded sidebar
--sidebar-width-icon3.5remWidth when collapsed to icons

Keyboard Shortcut

The sidebar can be toggled using Cmd+B (Mac) or Ctrl+B (Windows). Customize this by setting the keyboardShortcut prop:

<SidebarProvider keyboardShortcut="s">
{/* Toggle with Cmd+S or Ctrl+S */}
</SidebarProvider>

Events

The provider dispatches the following custom events:

EventDescription
sidebar:changeFired when sidebar open state changes
sidebar:mobile-changeFired when mobile sidebar state changes

Listen for state changes:

<script>
const provider = document.querySelector('[data-slot="sidebar-provider"]');
provider?.addEventListener("sidebar:change", (e) => {
const { open, state } = e.detail;
console.log("Sidebar is now:", state);
});
</script>

The main sidebar container.

PropTypeDefault
side"left" | "right""left"
variant"sidebar" | "floating" | "inset""sidebar"
collapsible"offcanvas" | "icon" | "none""offcanvas"
classstring-
<Sidebar side="left" variant="sidebar" collapsible="offcanvas">
{/* Content */}
</Sidebar>

Additional Notes:

  • side: Which side of the viewport the sidebar appears on
  • variant: Visual style - sidebar (default), floating (with border/shadow), or inset (rounded, use with SidebarInset)
  • collapsible: How the sidebar collapses - offcanvas (slides out), icon (collapses to icons), or none (non-collapsible)

SidebarTrigger

A button that toggles the sidebar state.

PropTypeDefault
variantButton variant"ghost"
sizeButton size"icon-sm"
classstring-
<SidebarTrigger />

Use the icon slot for a custom icon:

<SidebarTrigger>
<MenuIcon slot="icon" />
</SidebarTrigger>

SidebarHeader

Sticky header at the top of the sidebar.

PropTypeDefault
classstring-
<Sidebar>
<SidebarHeader>
<h2>My App</h2>
</SidebarHeader>
{/* ... */}
</Sidebar>

SidebarFooter

Sticky footer at the bottom of the sidebar.

PropTypeDefault
classstring-
<Sidebar>
{/* ... */}
<SidebarFooter>
<UserMenu />
</SidebarFooter>
</Sidebar>

SidebarContent

Scrollable content area for sidebar groups.

PropTypeDefault
classstring-
<SidebarContent>
<SidebarGroup />
<SidebarGroup />
</SidebarContent>

SidebarGroup

A section within the sidebar content.

PropTypeDefault
classstring-
<SidebarGroup>
<SidebarGroupLabel>Navigation</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>{/* Menu items */}</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>

SidebarGroupLabel

Label for a sidebar group.

PropTypeDefault
asChildbooleanfalse
classstring-
<SidebarGroupLabel>Application</SidebarGroupLabel>

SidebarGroupContent

Container for group content.

PropTypeDefault
classstring-

SidebarMenu

Container for menu items.

PropTypeDefault
classstring-
<SidebarMenu>
<SidebarMenuItem>{/* ... */}</SidebarMenuItem>
</SidebarMenu>

SidebarMenuItem

Individual menu item wrapper.

PropTypeDefault
classstring-

SidebarMenuButton

Interactive button or link within a menu item.

PropTypeDefault
hrefstring-
asChildbooleanfalse
isActivebooleanfalse
tooltipstring-
variant"default" | "outline""default"
size"default" | "sm" | "lg""default"
classstring-
<SidebarMenuButton href="/home" isActive={true} tooltip="Home">
<HomeIcon />
<span>Home</span>
</SidebarMenuButton>

Additional Notes:

  • href: When provided, renders as an anchor tag
  • isActive: Highlights the item as currently active
  • tooltip: Text shown in a tooltip when sidebar is collapsed to icons

SidebarMenuAction

Action button that appears alongside menu items.

PropTypeDefault
asChildbooleanfalse
showOnHoverbooleanfalse
classstring-
<SidebarMenuItem>
<SidebarMenuButton href="/projects">Projects</SidebarMenuButton>
<SidebarMenuAction showOnHover>
<PlusIcon />
</SidebarMenuAction>
</SidebarMenuItem>

SidebarMenuBadge

Badge displayed on a menu item.

PropTypeDefault
classstring-
<SidebarMenuItem>
<SidebarMenuButton>Inbox</SidebarMenuButton>
<SidebarMenuBadge>24</SidebarMenuBadge>
</SidebarMenuItem>

SidebarMenuSub

Container for submenu items.

PropTypeDefault
classstring-
<SidebarMenuItem>
<SidebarMenuButton>Settings</SidebarMenuButton>
<SidebarMenuSub>
<SidebarMenuSubItem>
<SidebarMenuSubButton href="/settings/profile">Profile</SidebarMenuSubButton>
</SidebarMenuSubItem>
</SidebarMenuSub>
</SidebarMenuItem>

SidebarMenuSubButton

Button for submenu items.

PropTypeDefault
hrefstring-
asChildbooleanfalse
isActivebooleanfalse
size"sm" | "md""md"
classstring-

SidebarMenuSkeleton

Loading skeleton for menu items.

PropTypeDefault
showIconbooleanfalse
classstring-
<SidebarMenu>
{Array.from({ length: 5 }).map(() => (
<SidebarMenuItem>
<SidebarMenuSkeleton showIcon />
</SidebarMenuItem>
))}
</SidebarMenu>

SidebarRail

A thin rail that allows toggling the sidebar by clicking or dragging.

PropTypeDefault
classstring-
<Sidebar>
{/* Content */}
<SidebarRail />
</Sidebar>

SidebarSeparator

Visual divider between sidebar sections.

PropTypeDefault
classstring-
<SidebarContent>
<SidebarGroup />
<SidebarSeparator />
<SidebarGroup />
</SidebarContent>

SidebarInset

Main content wrapper for use with the inset variant.

PropTypeDefault
classstring-
<SidebarProvider>
<Sidebar variant="inset" />
<SidebarInset>
<main>{/* Content */}</main>
</SidebarInset>
</SidebarProvider>

SidebarInput

Styled input for use in the sidebar (e.g., search).

PropTypeDefault
classstring-

Styling

Collapsible State Styling

Style elements based on the sidebar’s collapsible state:

<Sidebar collapsible="icon">
<SidebarContent>
<SidebarGroup class="group-data-[collapsible=icon]:hidden">
{/* Hidden when collapsed to icons */}
</SidebarGroup>
</SidebarContent>
</Sidebar>

Active State Styling

The SidebarMenuAction can be styled based on the menu button’s active state:

<SidebarMenuItem>
<SidebarMenuButton isActive />
<SidebarMenuAction class="peer-data-[active=true]/menu-button:opacity-100" />
</SidebarMenuItem>

Changelog

v1.0.1

  • Enhanced sidebar tooltip synchronization for mobile state changes

v1.0.0

  • Initial release with starwind v1.15.0