Status Tiles
The <x-wirekit::status-tiles> component renders a list of entities as colored
status tiles — a fleet light you read at a glance. Each tile is tinted by its
intent, but status never rides on color alone: every tile also carries a distinct
icon shape and a screen-reader status word, so the grid stays legible for
colorblind users and assistive technology (WCAG 1.4.1).
Reach for it when you have N of the same kind of thing and want to see all their states in one screen: thirty apps on one dashboard, a rack of services, a batch of jobs. For a two-dimensional cross of rows × columns, use Status Matrix instead.
Usage
Pass items — a list of ['key', 'label', 'intent'] maps. Add href to make a
tile a link, and meta for a small caption under the label.
Saying more than the intent does
intent is severity — five values, each with its own color and shape. Your domain probably has more states than that, and the ones that collide are usually the ones worth telling apart.
A health check that ran and reports a problem and a check that crashed are both danger. One points at your application, the other at your monitoring, and an operator sent to the wrong one loses the time you were trying to save them. The color cannot separate them, because it is the same color by definition.
Give the entry a status and the tile says your word instead of the derived one:
{{-- 1. Same severity, different states — the tiles now say so. --}}
<x-wirekit::status-tiles show-status :items="[
['key' => 'db', 'label' => 'Database', 'intent' => 'danger',
'status' => 'Failed', 'meta' => 'Connection refused'],
['key' => 'disk', 'label' => 'Disk space', 'intent' => 'danger',
'status' => 'Crashed', 'meta' => 'Check threw an exception'],
]" />
The word travels into the screen-reader text as well, so Status: Crashed is what a listener hears — the two never disagree. Everything else is unchanged: the tint, the shaped icon, and the Status: prefix all still come from intent, so a custom word cannot cost the tile its non-color channel.
Leave status out and nothing changes.
Legend
Set :legend="true" to show a count-per-intent legend above the grid. Only the
intents actually present are listed, each with its shaped icon, word, and count —
so the summary is readable without color too.
Clickable tiles
Give an item an href and its tile becomes a keyboard-operable link with a focus
ring — click through to the entity's detail view. Tiles without href stay static.
Density
The tiles fill a responsive grid. Pass columns (the same syntax as
Grid) to control how many sit per row — tighten it for a dense
fleet wall, loosen it for a handful of services.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items |
array |
[] |
The fleet — each entry a map: key, label, intent, optional href, meta, status. |
legend |
bool |
false |
Show a count-per-intent legend above the grid (only present intents listed). |
columns |
string |
'2 sm:3 md:4 lg:6' |
Responsive grid column spec, forwarded to Grid. |
gap |
string |
'sm' |
Grid gap token. |
showStatus |
bool |
false |
Promote the status word (Operational / Warning / Critical …) from the screen-reader-only span into a visible, intent-tinted caption on every tile. Off by default so existing tiles are unchanged. |
wrapMeta |
bool |
false |
Let the meta caption wrap onto several lines instead of clamping it to one. Off by default because a wrapping caption grows the whole grid row — turn it on when the caption is the message rather than a short count. |
scope |
string|null |
null |
Scoped personalization key. |
Each items entry accepts:
| Key | Type | Description |
|---|---|---|
key |
string |
Stable identifier, emitted as data-key (optional but recommended). |
label |
string |
The visible entity name. |
intent |
string |
success, warning, danger, info, or neutral. Anything else falls back to neutral. |
href |
string |
Makes the tile a link to the entity's detail view. |
meta |
string |
Optional small caption under the label (a count, a note). |
status |
string |
The word this tile reports. Defaults to the word derived from intent. |
Accessibility
- The grid is an ARIA
list; each tile is alistitem. Always pass anaria-labelnaming the fleet (aria-label="Fleet status"). - Status is never color-only (WCAG 1.4.1): each tile carries a distinct icon
shape and a visually-hidden status word (
Status: Critical), so colorblind and screen-reader users get the state without relying on the tint. - Linked tiles are real
<a>elements — tab-reachable, with a visible focus ring. - The legend repeats the same shaped-icon + word + count triad, readable in grayscale.
Keyboard Interaction
Status tiles carry no interaction model of their own — a tile is keyboard-operable
only when it is a link (has an href). Static tiles are read-only status displays
and are intentionally not focusable.
| Key | Action |
|---|---|
Tab |
Move focus to the next linked tile (skips static tiles) |
Enter |
Activate the focused linked tile (follow its href) |
Design Tokens
Tiles reuse the intent grammar of Badge — a soft color-mix
tinted surface with a matching 25%-tinted border and the -text intent color for
the icon. No new tokens are introduced.
| Token | Used for |
|---|---|
--color-wk-success / --color-wk-warning / --color-wk-danger / --color-wk-accent |
Tile tint + border per intent |
--color-wk-success-text / --color-wk-warning-text / --color-wk-danger-text / --color-wk-info-text |
Status icon color per intent |
--color-wk-bg-muted / --color-wk-border-subtle |
Neutral tile surface |
--radius-wk-md |
Tile corner radius |
--color-wk-ring |
Focus ring on linked tiles |
Further Reading
- Status Matrix — for a 2D rows × columns cross
- Badge — the intent grammar these tiles share
- WCAG 1.4.1 Use of Color