Sidebar
A slide-out drawer with backdrop overlay, smooth animations, and keyboard dismiss support.
9:41
Usage
app.tsx
1import { useState } from "react";2import { AppShell, Header, Content, Sidebar, NavGroup, NavItem } from "appshell-react";3import { Menu, Home, Settings, User, X } from "lucide-react";4 5export default function App() {6 const [open, setOpen] = useState(false);7 8 return (9 <AppShell safeArea>10 <Header11 behavior="fixed"12 logo={13 <button onClick={() => setOpen(true)}>14 <Menu className="size-5" />15 </button>16 }17 />18 19 <Sidebar open={open} onClose={() => setOpen(false)} side="left">20 <div className="flex items-center justify-between p-4 border-b">21 <span className="font-bold">Menu</span>22 <button onClick={() => setOpen(false)}>23 <X className="size-4" />24 </button>25 </div>26 27 <NavGroup title="Navigation" defaultOpen>28 <NavItem label="Home" icon={<Home />} active />29 <NavItem label="Profile" icon={<User />} />30 <NavItem label="Settings" icon={<Settings />} />31 </NavGroup>32 </Sidebar>33 34 <Content className="p-4">35 {/* Your content */}36 </Content>37 </AppShell>38 );39}Right Side
The sidebar can slide from either side:
tsx
1<Sidebar open={open} onClose={() => setOpen(false)} side="right">2 {/* Sidebar content */}3</Sidebar>Sidebar Props
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | Whether the sidebar is open |
| onClose | () => void | - | Callback when sidebar should close |
| side | "left" | "right" | "left" | Which side to slide from |
| className | string | - | Additional CSS classes |
| children | ReactNode | - | Sidebar content |
NavGroup Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | - | Group title |
| defaultOpen | boolean | true | Whether group is expanded by default |
| children | ReactNode | - | NavItem components |
NavItem Props
| Prop | Type | Default | Description |
|---|---|---|---|
| label | string | - | Item label |
| icon | ReactNode | - | Icon element |
| active | boolean | false | Whether this item is active |
| badge | number | string | - | Badge count or text |
| onClick | () => void | - | Click handler |
| href | string | - | Link destination |
Keyboard Support
The Sidebar automatically handles keyboard interactions:
- Escape closes the sidebar
- Focus is trapped inside the sidebar when open
- Focus returns to the trigger element when closed