Dashboard layout
A data-dense application shell combining a persistent side navigation, KPI summary strip, contextual alerts, and a sortable data table — the foundation for every policy management and reporting view in the product.
Overview
The dashboard layout is the primary chrome for authenticated, data-heavy product areas. It is not a component — it is an assembly of existing components arranged according to the layout rules in Spacing & layout. Any team building a list, report, or management screen should start from this pattern rather than designing the shell from scratch.
The layout solves three problems at once: it orients the user inside the app (persistent side nav), gives them an at-a-glance read on their portfolio (KPI strip), and lets them drill into individual records without navigating away (table + badge + actions).
Live pattern
The complete assembled pattern rendered from ws-* components. Every element below is production-usable — copy the markup and swap in real data.
Policy portfolio
<!-- Shell -->
<div class="pat-topbar">…</div>
<div class="pat-body">
<nav class="pat-sidenav">…</nav>
<main>
<nav class="ws-breadcrumb">…</nav>
<div class="ws-kpi-row">
<div class="ws-kpi-card">…</div>
<!-- repeat × 4 -->
</div>
<div class="ws-alert ws-alert--warning">…</div>
<!-- filter bar -->
<table class="ws-table">…</table>
<nav class="ws-pagination">…</nav>
</main>
</div>Anatomy
Seven distinct regions — each with a single responsibility. Understanding what each region owns prevents scope creep and keeps the layout coherent as content changes.
Brand identity, global search, user avatar, and theme toggle. Fixed to top. Never scroll it.
Persistent product navigation grouped by domain. The active item shows which area the user is in. Collapses to a hamburger icon below 960 px.
Breadcrumb for wayfinding, page title for context, and the primary action button(s) for this screen. Max two actions; primary on the right.
Four ws-kpi-card tiles summarising the most important numbers for this view. Collapse to 2-column at <900 px. Never add a 5th card — use a chart panel instead.
One ws-alert rendered only when there is an actionable issue the user must address. Do not use this region for passive information — it loses impact if always populated.
Inline search input + 1–3 select filters. Keep it to a single row; overflow filters go into a "More filters" drawer, not a second filter row.
The primary content region. Use ws-table with sortable column headers, row-level badges for status, avatar for the assigned user, and an action button per row. Always pair with ws-pagination.
Component inventory
Every ws-* component used in this pattern, what region it appears in, and where to find its documentation.
| Component | Region | Class | Documentation |
|---|---|---|---|
| Avatar + status | Topbar, table rows | ws-avatar, ws-avatar-wrap | Avatars & media |
| KPI card | KPI strip | ws-kpi-card | This pattern |
| Alert | Contextual alert | ws-alert ws-alert--warning | Feedback & status |
| Input | Filter bar | ws-input | Forms & inputs |
| Select | Filter bar | ws-select | Forms & inputs |
| Table | Data table | ws-table | Tables |
| Badge | Table — status column | ws-badge | Feedback & status |
| Button | Page header, table rows | ws-btn | Buttons |
| Pagination | Below table | ws-pagination | Navigation |
| Breadcrumb | Page header | ws-breadcrumb | Navigation |
| Media object | Table — client column | ws-media | Avatars & media |
Responsive behavior
| Breakpoint | Change |
|---|---|
| < 960 px | Side nav hides; hamburger toggle appears in topbar. Tap-opens as a full-height drawer over the content. |
| < 900 px | KPI strip collapses from 4-column to 2-column. |
| < 768 px | Table switches to a card-list view — each row becomes a ws-card with the same data fields stacked vertically. |
| < 480 px | Filter bar stacks vertically; search input spans full width. Page header actions move to a secondary "…" overflow menu. |
Accessibility
| Element | Requirement |
|---|---|
| Side navigation | role="navigation" with aria-label="Main navigation". Active link gets aria-current="page". |
| Table column sort | Sortable <th> elements use aria-sort="ascending" / "descending" / "none". |
| Select-all checkbox | aria-label="Select all rows". When partially checked, add aria-checked="mixed". |
| KPI card numbers | Wrap the numeric value in an aria-label that includes units: aria-label="284 active policies". |
| Pagination | Wrap in <nav aria-label="Pagination">. Each page button gets aria-label="Page N" and aria-current="page" on the active one. |
| Alert | Add role="alert" so urgent content is announced by screen readers without requiring focus. |