Admin Shell — Composition Pattern

admin-shell cluster-namespaced

The canonical composition pattern for an admin / SaaS / dashboard application. Built from cluster-namespaced bespoke children — every structural part has its own custom element with its own state-as-attribute semantics. The legacy raw-HTML form (<aside data-sidebar>, <main>, <dialog data-command>) was retired in v0.4.0 per ADR-0024; new code uses the bespoke shape exclusively per ADR-0023.

Canonical hierarchy

The live docs site you're reading runs inside one of these. The paste-ready reference at /site/examples/admin-dashboard matches this hierarchy exactly.

<admin-shell mode="rounded borderless"> <!-- LEADING sidebar — workspace switcher · nav rail · user switcher --> <admin-sidebar slot="leading" resizable collapsible> <admin-topbar slot="header"> <select-ui avatar="…" value="workspace" variant="ghost" style="flex:1"></select-ui> </admin-topbar> <section-ui> <nav-ui> <nav-item-ui icon="house" text="Home" selected></nav-item-ui> <nav-item-ui icon="gear" text="Settings"></nav-item-ui> </nav-ui> </section-ui> <admin-statusbar slot="footer"> <select-ui avatar="…" value="user" variant="ghost" style="flex:1"></select-ui> </admin-statusbar> <div data-resize></div> </admin-sidebar> <!-- MAIN content column — breadcrumb topbar · scrollable page · status footer --> <admin-content> <admin-topbar> <button-ui data-sidebar-toggle="leading" icon="sidebar" variant="ghost" size="sm"></button-ui> <breadcrumb-ui><a href="#">Home</a><span>Dashboard</span></breadcrumb-ui> <span data-spacer></span> <div data-actions> <button-ui text="Export" icon="download" variant="outline" size="sm"></button-ui> <button-ui text="+ New" variant="primary" size="sm"></button-ui> </div> </admin-topbar> <admin-scroll> <admin-page> <admin-page-header> <header> <div> <h1>Dashboard</h1> <div data-actions>…page-level actions…</div> </div> <p>Description.</p> </header> </admin-page-header> <admin-page-body> …grid-ui · card-ui · stat-ui · table-ui · etc.… </admin-page-body> </admin-page> </admin-scroll> <admin-statusbar> <span>My App</span> <span data-spacer></span> <span>v1.0.0</span> </admin-statusbar> </admin-content> <!-- TRAILING sidebar (optional) — context inspector / changelog rail --> <admin-sidebar slot="trailing" resizable collapsible hidden> <admin-topbar slot="header"> <span slot="heading">Inspector</span> <button-ui slot="action" data-sidebar-toggle="trailing" icon="x" variant="ghost" size="sm"></button-ui> </admin-topbar> <section-ui>…</section-ui> <div data-resize></div> </admin-sidebar> <!-- Command palette — top-level child, NOT nested in admin-content --> <admin-command> <command-ui placeholder="Search pages..."></command-ui> </admin-command> </admin-shell>

Part-by-part reference

Each part owns its own state-as-attribute semantics and has its own per-part docs page covering variants and permutations.

PartRoleVariants
<admin-shell> Behavior-only host. Wires sidebar toggle, command palette, ResizeObserver responsive collapse. mode="rounded borderless"
<admin-sidebar> · pattern Leading or trailing rail. Holds workspace switcher + nav + user switcher. Simple · grouped · with dividers · with sub-navs · workspace+user variants
<admin-topbar> Sticky band. Inside sidebar = workspace switcher; inside content = breadcrumb + actions; with slot="header" = sidebar header band. Breadcrumb + actions · breadcrumb only · with tabs · with search · with sidebar-toggle
<admin-content> · pattern Main column. Wraps topbar + scroll + statusbar. With trailing-aside subnav · with multiple pages (router-ui)
<admin-scroll> Scrollable region inside content. Wraps the page (or router). Single page · router · with section-rail aside
<admin-page> Page boundary inside admin-scroll. Holds page-header + page-body.
<admin-page-header> · pattern Page title band. Wraps <header> with title + actions + description. Regular · with actions · with tabs · with breadcrumb above · data-flush (no border)
<admin-page-body> Page content area. Holds the actual UI (grids, cards, tables, etc.).
<admin-statusbar> Footer band. Inside sidebar = user switcher; inside content = global status footer. User switcher · sign-in CTA · static brand · version + spacer
<admin-command> Cmd+K palette. Top-level child of admin-shell, self-stamps a <dialog>.

Authoring rules

Where to next

Live demos

Each demo is a real <admin-shell> rendered at fixed height. These are the patterns to emit when generating admin/SaaS/dashboard surfaces.

Maya Chen My AppDashboard

Dashboard

Welcome back. Here's what's happening today.

Page content goes here.

Adia Studio Kim Granlund Home

Home

Page body.