Account table
Customer accounts with health, plan and an agent note per row.
Customer accounts you can search and filter by plan. Each row shows the logo, plan tag, seats, a health bar and the MRR; click a row and it opens to the note the agent left — with an optional action button (like Draft email) that spins until its promise settles, then shows its done label. The rows stagger in again whenever the search or the filter changes.
| Account | Plan | Seats | Health | MRR |
|---|---|---|---|---|
| NNorthwind | Enterprise | 120 | 92 | $14,400 |
| LLumen Labs | Pro | 14 | 48 | $672 |
| FFable & Co | Team | 32 | 81 | $1,920 |
| OOrbit | Pro | 8 | 67 | $384 |
| KKite Health | Enterprise | 64 | 88 | $7,680 |
| PPaper Plane | Team | 21 | 34 | $1,260 |
Usage
<!-- include core.css + account-table.css -->
<div class="atb panel" data-c="account-table">
<div class="atb-h">
<div class="atb-s"><!-- search icon --><input placeholder="Search accounts"></div>
<div class="atb-fl">
<button class="chip sm on" data-p="">All</button>
<button class="chip sm" data-p="Team">Team</button>
<button class="chip sm" data-p="Pro">Pro</button>
<button class="chip sm" data-p="Enterprise">Enterprise</button>
</div>
</div>
<div class="atb-sc">
<table>
<thead><tr><th>Account</th><th>Plan</th><th>Seats</th><th>Health</th><th class="r">MRR</th></tr></thead>
<tbody><!-- rows rendered by account-table.js --></tbody>
</table>
</div>
</div>Properties
| Name | Type | Description |
|---|---|---|
accounts | AccountTableAccount[] | The account rows. Each has name, color, plan, seats, health (0–100), mrr and an optional note. |
plans | string[] | The plan filters after All. Defaults to the plans in accounts, in first-seen order. |
planTones | Record<string, Tone> | The tag colour per plan. Defaults to Enterprise purple, Pro blue, Team teal. |
plan / defaultPlan | string | The active plan filter, or '' for All. |
onPlanChange | (plan) => void | Called when a filter chip is picked. |
query / defaultQuery | string | The search text. Matches account names. |
onQueryChange | (query) => void | Called as the search text changes. |
open / defaultOpen | string | null | The account whose row is open, or null. |
onOpenChange | (name) => void | Called when a row opens or closes. |
action | { label; doneLabel?; onClick } | A button in the open row's note. Return a promise and it spins until it settles, then shows doneLabel. |
placeholder | string | The search field's placeholder. Defaults to Search accounts. |
emptyLabel | string | Shown when nothing matches the search and filter. |
Theming
Works in light and dark (data-theme="dark") and in the Soft style (data-style="soft"). The plan
tags run a little brighter than the shared tones — each plan takes its own saturated tint (blue,
purple, teal and so on), and the health bar fills green from 80, amber from 60 and red below, all
from the theme tokens. In Soft the panel, chips and tags are rounder.
Stat cards
A row of KPIs, each with its change against the period before and a sparkline, with a period switch that rolls the numbers and redraws the lines.
Segmented Control
One choice from a few views or options, with a white knob that slides to the picked one. Works as tabs or as a radio group, fully keyboard driven.