Skip to main content
WireKit
Copy for LLM

Status Matrix

One grid engine for every rows × columns status surface: a role-permission matrix (role × capability → allow / deny / inherit), a heat grid (cohort × period → value), a controls matrix (control × framework → met / at-risk / failing), or a preferences grid (type × channel → on / off). Pick the cell-type and the matrix renders the right interactive (or read-only) cell — on sticky row and column headers, inside a keyboard-reachable scroll region.

Every encoding is conveyed in text or shape, never color alone: tristate cells use distinct check / cross / dash glyphs, heat cells always print their value, and status cells render a labeled badge.

Role Permission Matrix

cell-type="tristate" with editable cycles each cell inherit → allow → deny on click or Enter/Space. Edited cells get a "changed" ring and the legend counts unsaved changes — ideal for an IAM grant editor.

Editable role × capability grants
Role Billing Members Projects Settings
Owner
Admin
Member
Guest
Allowed Denied Inherited unsaved change(s)

Heat Grid

cell-type="heat" color-mixes each cell's background from the surface toward the scale color by its normalized value — and always prints the value, so the grid stays legible for colorblind readers.

Retention cohort heat grid
Cohort Week 0 Week 1 Week 2 Week 3
January
100%
68%
54%
41%
February
100%
72%
60%
48%
March
100%
75%
63%
52%
0% 100%

Controls Matrix

cell-type="status" renders each value as an intent badge — common status words (met, at-risk, failing) map to success / warning / danger automatically. Perfect for a compliance control × framework grid.

Compliance controls × frameworks
Control SOC 2 ISO 27001 HIPAA
MFA enforced met met met
Encryption at rest met met at-risk
Tested backups at-risk failing failing

Preferences Grid

cell-type="toggle" with editable gives a type × channel on/off grid — e.g. a notification-preferences matrix.

Notification preferences (type × channel)
Notify me about Email Push SMS
Mentions
Comments
Weekly digest
On Off

Cell Types

cell-type Editable Cell renders Typical use
tristate yes inherit / allow / deny glyph role-permission matrix
toggle yes on / off dot preferences (type × channel)
status no intent badge compliance / controls grid
heat no color-scaled value retention / metric heatmap

Data Shapes

rows and columns are each [{key, label}]. cells is a value map keyed by "rowKey:colKey" — or a nested [rowKey => [colKey => value]] map; both are accepted.

// 1. Flat key shape
$cells = ['admin:billing' => 'allow', 'admin:users' => 'deny'];

// 2. Nested shape (equivalent)
$cells = ['admin' => ['billing' => 'allow', 'users' => 'deny']];

Status Value → Intent

status cells map these words automatically (case-insensitive); any other value renders neutral:

Intent Words
success met · pass · ok · active · compliant · done · on
warning at-risk · warning · pending · partial · review
danger failing · fail · error · inactive · breach · off

The Emitted Value (Editable)

When editable, every cell change emits the normalized map two ways — a bubbling cell-change event and a JSON hidden input — so wire:model and forms both bridge:

{{-- 1. Bind the JSON bridge to a Livewire property --}}
<x-wirekit::status-matrix
    cell-type="tristate"
    editable
    :rows="$roles"
    :columns="$capabilities"
    :cells="$grants"
    wire:model.live="grantsJson"
/>
// 2. Decode + persist the edited grants
public string $grantsJson = '{}';

public function save(): void
{
    $grants = json_decode($this->grantsJson, true) ?: [];
    // 3. $grants is ['admin:billing' => 'deny', ...] — persist as you like
    foreach ($grants as $key => $value) {
        [$role, $capability] = explode(':', $key);
        Grant::updateOrCreate(compact('role', 'capability'), ['value' => $value]);
    }
}

Props

Prop Type Default Description
rows array [] Row axis [{key, label}]
columns array [] Column axis [{key, label}]
cells array [] Value map ("row:col" => value or nested)
cellType string 'status' tristate · toggle · status · heat
editable bool false Make tristate / toggle interactive
cornerLabel string '' Top-left header cell (the row-axis name)
ariaLabel string 'Status matrix' Accessible name for the grid + scroll region
name string|null null Hidden-input name for form submission
heatFrom string var(--color-wk-warning) Heat ramp low end (cold) — a color/token reference
heatTo string var(--color-wk-danger) Heat ramp high end (hot) — a color/token reference
heatMin numeric 0 Heat scale lower bound
heatMax numeric 100 Heat scale upper bound
heatUnit string '' Suffix on heat value labels (e.g. %)
legend bool true Render the cell-type legend
scope string|null null Scoped personalization name

Accessibility

  • The grid is a role="grid" with scope="col" / scope="row" headers; the scroll wrapper is a labeled role="region" with tabindex="0" and a focus ring, so it is reachable and operable by keyboard (WCAG 2.1.1).
  • Every cell's state is in text or shape, never color alone: tristate cells carry the state word in their aria-label ("Admin, Billing: Denied") and use distinct glyphs; toggle cells expose role="switch" + aria-checked; heat cells always print their value; status cells render a labeled badge.
  • Interactive cells use a single tab stop (roving focus) into the grid; arrow keys then move between cells.

Keyboard Interaction

Key Action
Tab Enter / leave the grid (one stop), then reach the scroll region
Arrow keys Move focus between interactive cells
Enter / Space Cycle a tristate cell or flip a toggle

Design Tokens

Element Token
Sticky header surface --color-wk-bg-elevated
Grid border --color-wk-border
Allow glyph --color-wk-success
Deny glyph --color-wk-danger
Inherit glyph --color-wk-text-subtle
Changed-cell ring --color-wk-warning
Heat ramp (cold → hot) --color-wk-warning--color-wk-danger (override via heatFrom / heatTo)
Focus ring --color-wk-ring

Customization

Override the cell-type default and legend visibility via config/wirekit.php:

'components' => [
    'status-matrix' => [
        'cell-type' => 'tristate',
        'legend' => true,
    ],
],

Further Reading