Installation
Theme
Mode

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-shell

Overview

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.

Orbit AppOn track
Match
47 results
Tasks6Select a row to open detail

Composed from

Eight library components do all the work — the block wires them together with thin flex glue and passes data through.

  • Sidebarthe 264px collapsible rail — workspace switcher, ⌘K search, grouped nav with submenus and badges, account footer.
  • Top Barthe global row (panel toggle, breadcrumbs, command search, notifications, New, avatar) plus the page row (title, view tabs, actions).
  • Filter Barthe faceted chips above the view — add-filter picker, is/is-not values, Match All/Any, live result count.
  • Drawerthe task detail panel that slides in when a list row is selected.
  • Dropdown Menuevery popover in the shell — search recents, notifications, quick-create, account, workspace switcher, filter, sort, and overflow.
  • Buttonthe New split-button and the drawer's footer actions.
  • Badgethe “On track” status pill beside the page title.
  • Avataridentity 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.

defaultCollapsed + density="compact"
Orbit AppOn track
Match
47 results
Tasks6Select a row to open detail
Slots pared back — pageBar={null} filterBar={null}, custom children
children — your page goes here

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/> detail

Props

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.

PropTypeDefaultDescription
navAppShellNavGroup[]APP_SHELL_NAVGrouped sidebar navigation — items take an icon, an optional badge, or nested children.
activeId / defaultActiveIdstring"p-orbit"Selected nav id, controlled or uncontrolled; pair the controlled form with onNavigate.
onNavigate(id: string) => voidFires when a nav item or submenu leaf is clicked.
defaultOpenGroupsstring[]["projects"]Submenu ids that start expanded.
defaultCollapsedbooleanfalseStart with the 64px icon rail. The top-bar toggle, sidebar trigger, edge rail, and ⌘B all stay in sync.
storageKeystring | falsefalseSidebar persistence namespace; false keeps instances independent (docs demos).
workspaces / userAppShellWorkspace[] / AppShellUserAcme Inc… / Sam ChenIdentity for the switcher, account menus, and footer.
density"comfortable" | "compact""comfortable"Top bar sizing — flows into every row and control.
breadcrumbs / search / topBarEndReactNodeTop-bar slots (leading, center, trailing). undefined renders the spec default; null hides the region.
pageBar / filterBarReactNodeThe second top-bar row and the toolbar above the content — same undefined/null contract.
childrenReactNodeThe 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.

⌘ / Ctrl + BToggles the sidebar rail (with focus inside it)
EscCloses any open popover — and the detail Drawer
↑ ↓ ↵Navigate and pick inside every menu popover
TabReaches every control — toggles, chips, rows are real buttons