|
| 1 | +--- |
| 2 | +title: "AppShell" |
| 3 | +description: "Main application shell with sidebar and header layout" |
| 4 | +--- |
| 5 | + |
| 6 | +import { ComponentDemo, DemoGrid } from '@/app/components/ComponentDemo'; |
| 7 | + |
| 8 | +The AppShell component provides the main application layout structure with an integrated sidebar, header, and content area. It's the foundation for building enterprise applications with ObjectUI. |
| 9 | + |
| 10 | +## Basic Usage |
| 11 | + |
| 12 | +```typescript |
| 13 | +import { AppShell } from '@object-ui/layout'; |
| 14 | +import { SidebarNav } from '@object-ui/layout'; |
| 15 | + |
| 16 | +<AppShell |
| 17 | + sidebar={ |
| 18 | + <SidebarNav |
| 19 | + items={[ |
| 20 | + { label: 'Dashboard', href: '/', icon: 'home' }, |
| 21 | + { label: 'Users', href: '/users', icon: 'users' }, |
| 22 | + { label: 'Settings', href: '/settings', icon: 'settings' } |
| 23 | + ]} |
| 24 | + /> |
| 25 | + } |
| 26 | + navbar={ |
| 27 | + <div className="flex items-center gap-4"> |
| 28 | + <span className="font-semibold">My App</span> |
| 29 | + </div> |
| 30 | + } |
| 31 | +> |
| 32 | + {/* Your page content */} |
| 33 | + <div>Main content area</div> |
| 34 | +</AppShell> |
| 35 | +``` |
| 36 | + |
| 37 | +## Component Props |
| 38 | + |
| 39 | +```typescript |
| 40 | +interface AppShellProps { |
| 41 | + sidebar?: React.ReactNode; // Sidebar content (usually SidebarNav) |
| 42 | + navbar?: React.ReactNode; // Top navbar content (logo, search, user menu) |
| 43 | + children: React.ReactNode; // Main content area |
| 44 | + className?: string; // Additional CSS classes for content area |
| 45 | + defaultOpen?: boolean; // Sidebar default state (default: true) |
| 46 | +} |
| 47 | +``` |
| 48 | +
|
| 49 | +## Features |
| 50 | +
|
| 51 | +### Responsive Sidebar |
| 52 | +
|
| 53 | +The AppShell includes a responsive sidebar that: |
| 54 | +- Collapses on mobile devices |
| 55 | +- Can be toggled via hamburger menu |
| 56 | +- Persists state across page navigations |
| 57 | +- Supports smooth animations |
| 58 | +
|
| 59 | +### Header Bar |
| 60 | +
|
| 61 | +The header bar provides: |
| 62 | +- Sidebar toggle button |
| 63 | +- Custom navbar content area |
| 64 | +- Fixed height (64px / 4rem) |
| 65 | +- Border bottom separator |
| 66 | +- Background matching app theme |
| 67 | +
|
| 68 | +### Content Area |
| 69 | +
|
| 70 | +The main content area features: |
| 71 | +- Responsive padding (4 on mobile, 6 on desktop) |
| 72 | +- Automatic scrolling |
| 73 | +- Flexible height (fills viewport) |
| 74 | +- Custom className support |
| 75 | +
|
| 76 | +## Layout Structure |
| 77 | +
|
| 78 | +``` |
| 79 | +┌─────────────────────────────────────┐ |
| 80 | +│ Header (Sidebar Toggle + Nav) │ |
| 81 | +├──────────┬──────────────────────────┤ |
| 82 | +│ │ │ |
| 83 | +│ Sidebar │ Main Content Area │ |
| 84 | +│ │ │ |
| 85 | +│ │ │ |
| 86 | +│ │ │ |
| 87 | +└──────────┴──────────────────────────┘ |
| 88 | +``` |
| 89 | +
|
| 90 | +## Sidebar Configuration |
| 91 | +
|
| 92 | +### Default Open State |
| 93 | +
|
| 94 | +Control whether sidebar is open by default: |
| 95 | +
|
| 96 | +```typescript |
| 97 | +<AppShell defaultOpen={false}> |
| 98 | + {/* Sidebar starts collapsed */} |
| 99 | +</AppShell> |
| 100 | +``` |
| 101 | +
|
| 102 | +### Collapsible Sidebar |
| 103 | +
|
| 104 | +The sidebar can be toggled via: |
| 105 | +- Hamburger menu button (always visible) |
| 106 | +- Keyboard shortcuts (when implemented) |
| 107 | +- Programmatic control |
| 108 | +
|
| 109 | +## Navbar Content |
| 110 | +
|
| 111 | +The navbar area is flexible and can contain: |
| 112 | +
|
| 113 | +### Logo and Title |
| 114 | +
|
| 115 | +```typescript |
| 116 | +navbar={ |
| 117 | + <div className="flex items-center gap-2"> |
| 118 | + <img src="/logo.svg" alt="Logo" className="h-8 w-8" /> |
| 119 | + <span className="font-semibold text-lg">My Application</span> |
| 120 | + </div> |
| 121 | +} |
| 122 | +``` |
| 123 | +
|
| 124 | +### Search Bar |
| 125 | +
|
| 126 | +```typescript |
| 127 | +navbar={ |
| 128 | + <div className="flex-1 max-w-md"> |
| 129 | + <Input placeholder="Search..." /> |
| 130 | + </div> |
| 131 | +} |
| 132 | +``` |
| 133 | +
|
| 134 | +### User Menu |
| 135 | +
|
| 136 | +```typescript |
| 137 | +navbar={ |
| 138 | + <div className="flex items-center gap-4 ml-auto"> |
| 139 | + <NotificationsButton /> |
| 140 | + <UserDropdown /> |
| 141 | + </div> |
| 142 | +} |
| 143 | +``` |
| 144 | +
|
| 145 | +## Complete Example |
| 146 | +
|
| 147 | +```typescript |
| 148 | +import { AppShell, SidebarNav } from '@object-ui/layout'; |
| 149 | +import { Avatar, Button, Input } from '@object-ui/components'; |
| 150 | + |
| 151 | +function App() { |
| 152 | + return ( |
| 153 | + <AppShell |
| 154 | + defaultOpen={true} |
| 155 | + sidebar={ |
| 156 | + <SidebarNav |
| 157 | + header={{ |
| 158 | + logo: '/logo.svg', |
| 159 | + title: 'ObjectUI' |
| 160 | + }} |
| 161 | + items={[ |
| 162 | + { |
| 163 | + label: 'Dashboard', |
| 164 | + href: '/', |
| 165 | + icon: 'layout-dashboard', |
| 166 | + badge: '12' |
| 167 | + }, |
| 168 | + { |
| 169 | + label: 'Projects', |
| 170 | + href: '/projects', |
| 171 | + icon: 'folder', |
| 172 | + children: [ |
| 173 | + { label: 'Active', href: '/projects/active' }, |
| 174 | + { label: 'Archived', href: '/projects/archived' } |
| 175 | + ] |
| 176 | + }, |
| 177 | + { |
| 178 | + label: 'Team', |
| 179 | + href: '/team', |
| 180 | + icon: 'users' |
| 181 | + }, |
| 182 | + { |
| 183 | + label: 'Settings', |
| 184 | + href: '/settings', |
| 185 | + icon: 'settings' |
| 186 | + } |
| 187 | + ]} |
| 188 | + footer={ |
| 189 | + <div className="p-4 border-t"> |
| 190 | + <Button variant="outline" className="w-full"> |
| 191 | + Upgrade Plan |
| 192 | + </Button> |
| 193 | + </div> |
| 194 | + } |
| 195 | + /> |
| 196 | + } |
| 197 | + navbar={ |
| 198 | + <div className="flex items-center justify-between w-full"> |
| 199 | + {/* Search */} |
| 200 | + <div className="flex-1 max-w-md"> |
| 201 | + <Input |
| 202 | + placeholder="Search..." |
| 203 | + className="w-full" |
| 204 | + /> |
| 205 | + </div> |
| 206 | + |
| 207 | + {/* Right side items */} |
| 208 | + <div className="flex items-center gap-4"> |
| 209 | + <Button variant="ghost" size="icon"> |
| 210 | + <Bell className="h-5 w-5" /> |
| 211 | + </Button> |
| 212 | + <Avatar> |
| 213 | + <AvatarFallback>JD</AvatarFallback> |
| 214 | + </Avatar> |
| 215 | + </div> |
| 216 | + </div> |
| 217 | + } |
| 218 | + className="bg-gray-50" |
| 219 | + > |
| 220 | + {/* Main content */} |
| 221 | + <div className="max-w-7xl"> |
| 222 | + <h1 className="text-2xl font-bold mb-4">Dashboard</h1> |
| 223 | + {/* Page content */} |
| 224 | + </div> |
| 225 | + </AppShell> |
| 226 | + ); |
| 227 | +} |
| 228 | +``` |
| 229 | + |
| 230 | +## With Page Component |
| 231 | + |
| 232 | +Combine AppShell with the Page component for complete layouts: |
| 233 | + |
| 234 | +```typescript |
| 235 | +<AppShell sidebar={<SidebarNav items={navItems} />}> |
| 236 | + <Page |
| 237 | + title="Dashboard" |
| 238 | + description="Welcome to your dashboard" |
| 239 | + body={[ |
| 240 | + { type: 'text', content: 'Dashboard content' } |
| 241 | + ]} |
| 242 | + /> |
| 243 | +</AppShell> |
| 244 | +``` |
| 245 | + |
| 246 | +## Styling |
| 247 | + |
| 248 | +The AppShell uses Tailwind CSS and Shadcn UI components: |
| 249 | + |
| 250 | +- `SidebarProvider`: Manages sidebar state |
| 251 | +- `SidebarTrigger`: Hamburger menu button |
| 252 | +- `SidebarInset`: Content area wrapper |
| 253 | + |
| 254 | +## Accessibility |
| 255 | + |
| 256 | +The AppShell includes: |
| 257 | +- Proper ARIA labels for sidebar toggle |
| 258 | +- Keyboard navigation support |
| 259 | +- Focus management |
| 260 | +- Screen reader announcements |
| 261 | + |
| 262 | +## Related |
| 263 | + |
| 264 | +- [SidebarNav](/docs/core/sidebar-nav) - Sidebar navigation component |
| 265 | +- [PageHeader](/docs/core/page-header) - Page header component |
| 266 | +- [Page](/docs/components/layout/page) - Page layout component |
0 commit comments