sidebar.tsx
Overview
The sidebar.tsx file provides a comprehensive React sidebar component system designed for flexible layouts that adapt to desktop and mobile environments. It offers:
A context provider managing sidebar state (expanded/collapsed, open/closed).
Responsive behavior with mobile-specific handling via off-canvas sheets.
Multiple sidebar variants (
sidebar,floating,inset) and collapsible modes (offcanvas,icon,none).A rich set of composable sidebar-related UI components such as headers, footers, groups, menus, buttons, inputs, separators, and more.
Keyboard shortcut support (
Ctrl/Cmd + B) for toggling sidebar visibility.Integration with other UI primitives such as buttons, inputs, tooltips, skeleton loaders, and sheets.
This file is designed to be a central piece of the UI layout system, enabling the consistent creation and management of sidebars throughout the application with accessibility and responsiveness in mind.
Components, Hooks, and Utilities
1. SidebarContext and useSidebar
Purpose:
Provide and consume sidebar state and controls throughout the component tree.SidebarContextType:
type SidebarContextType = { state: 'expanded' | 'collapsed'; open: boolean; setOpen: (open: boolean) => void; openMobile: boolean; setOpenMobile: (open: boolean) => void; isMobile: boolean; toggleSidebar: () => void; };useSidebar()
Hook to access the sidebar context. Throws an error if used outsideSidebarProvider.Usage:
const { open, toggleSidebar } = useSidebar();
2. SidebarProvider
Description:
Context provider managing the sidebar's open/closed state, mobile responsiveness, and keyboard shortcut for toggling.Props:
defaultOpen?: boolean- Initial open state (default:true).open?: boolean- Controlled open state.onOpenChange?: (open: boolean) => void- Callback when open state changes.Inherits all
divHTML element props.
Behavior:
Uses internal state or controlled props for sidebar open state.
Manages separate open state for mobile (
openMobile).Persists sidebar open state with a cookie (
sidebar_state).Keyboard shortcut:
Ctrl/Cmd + Btoggles sidebar.Provides context with state, setters, and toggling function.
Example:
<SidebarProvider defaultOpen={false}> <App /> </SidebarProvider>
3. Sidebar
Description:
Main sidebar container component that adapts to device type and variant.Props:
side?: 'left' | 'right'- Side of screen (default:'left').variant?: 'sidebar' | 'floating' | 'inset'- Visual style (default:'sidebar').collapsible?: 'offcanvas' | 'icon' | 'none'- Collapsibility mode (default:'offcanvas').Inherits all
divprops.
Behavior:
On mobile, renders an off-canvas
Sheet.On desktop, supports collapsing with width animations.
Supports different visual variants and sides.
Example:
<Sidebar side="right" variant="floating" collapsible="icon"> <SidebarHeader>Menu</SidebarHeader> <SidebarContent>...</SidebarContent> </Sidebar>
4. SidebarTrigger
Description:
Button component to toggle sidebar visibility.Props:
Inherits props fromButtoncomponent.Usage:
<SidebarTrigger aria-label="Toggle Sidebar" />Displays a left panel icon and toggles sidebar on click.
5. SidebarRail
Description:
Invisible clickable rail on the edge of the sidebar for toggling.Props:
Inherits allbuttonprops.Usage:
Positioned absolutely for resizing/toggling sidebar.
6. SidebarInset
Description:
Main content wrapper adapted for inset sidebars.Props:
Inheritsmainelement props.Usage:
<SidebarInset> Main content here </SidebarInset>
7. UI Primitive Components
All these components are forwardRef React components designed for flexible composition within the sidebar:
Component | Description |
|---|---|
| Styled input box for sidebar search or filters. |
| Container for sidebar header content. |
| Container for sidebar footer content. |
| Visual divider line between sidebar sections. |
| Scrollable container for main sidebar content. |
| Wrapper for grouping sidebar items. |
| Label for sidebar groups, supports |
| Action button within a group, supports |
| Container for sidebar menu lists ( |
| Individual menu item ( |
| Menu item button with variants, active state, tooltip support. |
| Action button inside menu items, optionally shown on hover. |
| Badge display for menu items (e.g., notifications). |
| Loading placeholder for menu items with optional icon. |
| Sub-menu list container ( |
| Sub-menu item ( |
| Sub-menu anchor/button, supports size and active state. |
Notable props:
asChild(boolean): Render with a different underlying component using Radix'sSlot.isActive(boolean): Marks menu buttons as active.tooltip: String or tooltip props forSidebarMenuButton.variantandsize(forSidebarMenuButton): Styling variants.
Example usage:
<SidebarMenu> <SidebarMenuItem> <SidebarMenuButton isActive tooltip="Home"> Home </SidebarMenuButton> <SidebarMenuAction> <EditIcon /> </SidebarMenuAction> </SidebarMenuItem> </SidebarMenu>
Important Implementation Details
Responsive Design:
Uses a custom hookuseIsMobileto detect device type and switches between sidebar modes accordingly.State Persistence:
Sidebar state (expandedorcollapsed) is saved in a cookie (sidebar_state) with a 7-day expiry, enabling state persistence across sessions.Keyboard Shortcut:
Listens globally forCtrl/Cmd + Bkeypress to toggle sidebar visibility.CSS Variables:
Defines CSS custom properties for sidebar widths (--sidebar-width,--sidebar-width-icon, etc.) allowing dynamic styling based on state and variant.Collapsibility Modes:
offcanvas: Sidebar slides in/out.icon: Sidebar collapses to icon-only width.none: Sidebar fixed, non-collapsible.
Accessibility:
Buttons have
aria-labelsandsr-onlytext for screen readers.Keyboard focus styles via
focus-visibleand ring styles.
Styling:
Utilizesclass-variance-authority(CVA) for dynamic class variants on menu buttons.Composition:
All components useReact.forwardReffor ref forwarding, enabling advanced composition patterns.
Integration and Interaction with the System
UI Library Dependencies:
Imports reusable UI primitives from the application's UI library (e.g.,Button,Input,Tooltip,Sheet,Skeleton,Separator).Hooks:
UtilizesuseIsMobilehook to adapt to screen sizes.Context:
TheSidebarProviderwraps the app or relevant subtree to provide sidebar state globally.Keyboard Handling:
Handles global keyboard events for user accessibility.Cookie Usage:
Sidebar open/closed state is persisted via a cookie, enabling consistent experience across page reloads.Layout Impact:
The sidebar components interact with layout by providing widths and spacing via CSS variables and data attributes, enabling responsive and variant-based layout changes.
Usage Example
import {
SidebarProvider,
Sidebar,
SidebarHeader,
SidebarContent,
SidebarFooter,
SidebarTrigger,
SidebarMenu,
SidebarMenuItem,
SidebarMenuButton,
} from '@/components/sidebar';
function AppLayout() {
return (
<SidebarProvider defaultOpen>
<Sidebar>
<SidebarHeader>
<h1>My App</h1>
</SidebarHeader>
<SidebarContent>
<SidebarMenu>
<SidebarMenuItem>
<SidebarMenuButton isActive>Dashboard</SidebarMenuButton>
</SidebarMenuItem>
<SidebarMenuItem>
<SidebarMenuButton>Settings</SidebarMenuButton>
</SidebarMenuItem>
</SidebarMenu>
</SidebarContent>
<SidebarFooter>
<SidebarTrigger />
</SidebarFooter>
</Sidebar>
<main>
{/* Main content */}
</main>
</SidebarProvider>
);
}
Mermaid Component Diagram
componentDiagram
direction TB
SidebarProvider --provides--> SidebarContext
SidebarContext <.. useSidebar
SidebarProvider --> Sidebar
Sidebar --> SidebarHeader
Sidebar --> SidebarContent
Sidebar --> SidebarFooter
SidebarContent --> SidebarMenu
SidebarMenu --> SidebarMenuItem
SidebarMenuItem --> SidebarMenuButton
SidebarMenuItem --> SidebarMenuAction
SidebarMenuItem --> SidebarMenuBadge
SidebarMenu --> SidebarMenuSub
SidebarMenuSub --> SidebarMenuSubItem
SidebarMenuSubItem --> SidebarMenuSubButton
Sidebar --> SidebarRail
Sidebar --> SidebarSeparator
Sidebar --> SidebarInset
SidebarHeader --> SidebarInput
SidebarGroup --> SidebarGroupLabel
SidebarGroup --> SidebarGroupAction
SidebarGroup --> SidebarGroupContent
SidebarTrigger --> Button
SidebarMenuButton --> Button
SidebarMenuAction --> Button
SidebarMenuSkeleton --> Skeleton
SidebarMenuButton --> Tooltip
Summary
The sidebar.tsx file defines an extensible, accessible, and responsive sidebar system for React applications. Through context management, versatile variants, and a rich set of UI subcomponents, it enables developers to build complex sidebar navigation patterns adapted for both desktop and mobile usage, with state persistence and keyboard accessibility baked in.