Blocks
App Shell
The full application frame, assembled entirely from the library: a collapsible Sidebar down the left, a two-row Top Bar across the top, a Filter Bar over the working area, and a detail view whose rows open a Drawer. This block is composition only — every behavior belongs to the underlying components; the shell adds a flex layout, demo data, and slots to swap each region out.
npx shadcn@latest add @orbit/app-shellOverview
The assembled screen from the spec, live. Collapse the rail from either toggle (or ⌘/Ctrl+B with focus in the rail), open the search, notification, and account popovers, edit the filter chips, and click a task row to slide in the detail drawer.
Composed from
Eight library components do all the work — the block wires them together with thin flex glue and passes data through.
- Sidebar — the 264px collapsible rail — workspace switcher, ⌘K search, grouped nav with submenus and badges, account footer.
- Top Bar — the global row (panel toggle, breadcrumbs, command search, notifications, New, avatar) plus the page row (title, view tabs, actions).
- Filter Bar — the faceted chips above the view — add-filter picker, is/is-not values, Match All/Any, live result count.
- Drawer — the task detail panel that slides in when a list row is selected.
- Dropdown Menu — every popover in the shell — search recents, notifications, quick-create, account, workspace switcher, filter, sort, and overflow.
- Button — the New split-button and the drawer's footer actions.
- Badge — the “On track” status pill beside the page title.
- Avatar — identity everywhere — top bar, notification rows, account menus, sidebar footer.
Variant states
The shell inherits its variants from the parts it composes: the Sidebar's collapsed 64px icon rail (badges become dots, labels become hover tooltips) and the Top Bar's compact density (48/40px rows, smaller controls). Both shown together below.
How it's assembled
The component tree. Regions marked as slots (breadcrumbs, search, topBarEnd, pageBar, filterBar, children) accept any node — pass null to remove one, or leave it undefined for the spec's default.
<AppShell> flex h-full · bg token
├─ <Sidebar collapsed onCollapsedChange> 264px rail (64px collapsed)
│ ├─ <SidebarHeader> workspace switcher (Menu) + <SidebarTrigger/>
│ ├─ search field ⌘K stand-in
│ ├─ <SidebarContent> <SidebarGroup(Label)> → <SidebarMenu(Button)>
│ │ └ <SidebarSubmenu(Trigger/Content/Item)>
│ ├─ <SidebarFooter> account row (Menu + Avatar)
│ └─ <SidebarRail/>
└─ column (flex-1)
├─ <TopBar density>
│ ├─ <TopBarRow> toggle · <TopBarBreadcrumbs/> ·
│ │ <TopBarSearch/> (Menu) · bell (Menu) ·
│ │ New (Button + Menu) · Avatar (Menu)
│ └─ <TopBarRow tier="page"> <TopBarTitle status={<Badge/>}> ·
│ <TopBarTabs/> · <TopBarActions/> (Menus)
└─ <main class="p-[18px] gap-4">
├─ <FilterBar fields filters …/> controlled, spec's default chips
└─ {children} demo: task list rows → <Drawer/> detailProps
Everything is optional — <AppShell> with no props renders the spec's demo screen. The exported APP_SHELL_NAV, APP_SHELL_FILTER_FIELDS, APP_SHELL_TASKS, and friends are the spec datasets, ready to fork.
| Prop | Type | Default | Description |
|---|---|---|---|
| nav | AppShellNavGroup[] | APP_SHELL_NAV | Grouped sidebar navigation — items take an icon, an optional badge, or nested children. |
| activeId / defaultActiveId | string | "p-orbit" | Selected nav id, controlled or uncontrolled; pair the controlled form with onNavigate. |
| onNavigate | (id: string) => void | — | Fires when a nav item or submenu leaf is clicked. |
| defaultOpenGroups | string[] | ["projects"] | Submenu ids that start expanded. |
| defaultCollapsed | boolean | false | Start with the 64px icon rail. The top-bar toggle, sidebar trigger, edge rail, and ⌘B all stay in sync. |
| storageKey | string | false | false | Sidebar persistence namespace; false keeps instances independent (docs demos). |
| workspaces / user | AppShellWorkspace[] / AppShellUser | Acme Inc… / Sam Chen | Identity for the switcher, account menus, and footer. |
| density | "comfortable" | "compact" | "comfortable" | Top bar sizing — flows into every row and control. |
| breadcrumbs / search / topBarEnd | ReactNode | — | Top-bar slots (leading, center, trailing). undefined renders the spec default; null hides the region. |
| pageBar / filterBar | ReactNode | — | The second top-bar row and the toolbar above the content — same undefined/null contract. |
| children | ReactNode | — | The main detail area. <AppShellDemoContent/> is the spec's task list + Drawer. |
Keyboard & accessibility
The shell adds no interaction of its own — every contract comes from the composed parts: the Sidebar's collapse shortcut and hover tooltips when collapsed, Base UI menus behind every popover, and the Drawer's focus trap. See each component's page for the full details.