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.
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.
Each part owns its own state-as-attribute semantics and has its own per-part docs page covering variants and permutations.
| Part | Role | Variants |
|---|---|---|
<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>. |
— |
<admin-shell>, use <admin-sidebar>, <admin-content>, <admin-topbar>, <admin-statusbar>, <admin-page>, <admin-command>. Don't use raw <aside>, <main>, <dialog> — they no longer style or wire (ADR-0024).<nav-ui> + <nav-item-ui>. NOT <menu-ui> / <menu-item-ui> — those are popover action menus (dropdowns), wrong primitive for nav.<select-ui avatar="…" value="…" variant="ghost">. Auto-stamps avatar + label + caret-up-down row. The <menu-ui>-with-button-trigger form documented elsewhere is the v0.5.x legacy shape; new code uses <select-ui>.<header>. The shape is <admin-page-header><header><div><h1>…</h1><div data-actions>…</div></div><p>…</p></header></admin-page-header>. Add data-flush on the inner <header> to drop the bottom border.<nav-item-ui> rows centre to their icon when the rail is collapsed — every row needs an icon= attribute or a [slot="icon"] child to remain legible.shell.querySelector('admin-sidebar[slot="leading"]').hasAttribute('collapsed'). Style cross-cuts via :has(); no getBoundingClientRect math.Each demo is a real <admin-shell> rendered at fixed height. These are the patterns to emit when generating admin/SaaS/dashboard surfaces.
Welcome back. Here's what's happening today.
Page content goes here.
Page body.