Stat cards
Examples
Section titled “Examples”Total Generations
1,234
42 completed / 12 pending
Total Generations
1,234
42 completed / 12 pending
<div class="card stat-card"> <p class="stat-card-label">Total Generations</p> <p class="stat-card-value">1,234</p> <p class="stat-card-detail">42 completed / 12 pending</p></div><StatCard label="Total Generations" value="1,234" detail="42 completed / 12 pending"/>With icon
Section titled “With icon”Orders today
128
14 awaiting fulfilment
Orders today
128
14 awaiting fulfilment
<div class="card stat-card"> <p class="stat-card-label"> <i class="ti ti-shopping-bag" aria-hidden="true"></i> Orders today </p> <p class="stat-card-value">128</p> <p class="stat-card-detail">14 awaiting fulfilment</p></div><StatCard icon={IconShoppingBag} label="Orders today" value="128" detail="14 awaiting fulfilment"/>Compact + bordered
Section titled “Compact + bordered”Active sessions
3,402
+12% vs last hour
Active sessions
3,402
+12% vs last hour
<div class="card stat-card card-compact card-bordered"> <p class="stat-card-label">Active sessions</p> <p class="stat-card-value">3,402</p> <p class="stat-card-detail">+12% vs last hour</p></div><StatCard compact bordered label="Active sessions" value="3,402" detail="+12% vs last hour"/>Color variants
Section titled “Color variants”Uptime
99.98%
last 30 days
Failed jobs
37
+29 vs yesterday
Queue depth
1,204
approaching limit
Archived
8,510
read-only
Uptime
99.98%
last 30 days
Failed jobs
37
+29 vs yesterday
Queue depth
1,204
approaching limit
Archived
8,510
read-only
<div class="grid grid-cols-2 gap-4 md:grid-cols-4"> <div class="card stat-card card-success"> <p class="stat-card-label">Uptime</p> <p class="stat-card-value">99.98%</p> <p class="stat-card-detail">last 30 days</p> </div> <div class="card stat-card card-danger"> <p class="stat-card-label">Failed jobs</p> <p class="stat-card-value">37</p> <p class="stat-card-detail">+29 vs yesterday</p> </div> <div class="card stat-card card-warning"> <p class="stat-card-label">Queue depth</p> <p class="stat-card-value">1,204</p> <p class="stat-card-detail">approaching limit</p> </div> <div class="card stat-card card-muted"> <p class="stat-card-label">Archived</p> <p class="stat-card-value">8,510</p> <p class="stat-card-detail">read-only</p> </div></div><div className="grid grid-cols-2 gap-4 md:grid-cols-4"> <StatCard variant="success" label="Uptime" value="99.98%" detail="last 30 days" /> <StatCard variant="danger" label="Failed jobs" value="37" detail="+29 vs yesterday" /> <StatCard variant="warning" label="Queue depth" value="1,204" detail="approaching limit" /> <StatCard variant="muted" label="Archived" value="8,510" detail="read-only" /></div>Dashboard grid
Section titled “Dashboard grid”Users
12,408
+1,204 this week
Active now
342
peak 412
Orders
128
14 pending
Revenue
$8.4k
+8% vs target
Users
12,408
+1,204 this week
Active now
342
peak 412
Orders
128
14 pending
Revenue
$8.4k
+8% vs target
<div class="grid grid-cols-2 gap-4 md:grid-cols-4"> <div class="card stat-card"> <p class="stat-card-label"> <i class="ti ti-users" aria-hidden="true"></i> Users </p> <p class="stat-card-value">12,408</p> <p class="stat-card-detail">+1,204 this week</p> </div> <div class="card stat-card"> <p class="stat-card-label"> <i class="ti ti-activity" aria-hidden="true"></i> Active now </p> <p class="stat-card-value">342</p> <p class="stat-card-detail">peak 412</p> </div> <div class="card stat-card"> <p class="stat-card-label"> <i class="ti ti-shopping-bag" aria-hidden="true"></i> Orders </p> <p class="stat-card-value">128</p> <p class="stat-card-detail">14 pending</p> </div> <div class="card stat-card"> <p class="stat-card-label"> <i class="ti ti-cash" aria-hidden="true"></i> Revenue </p> <p class="stat-card-value">$8.4k</p> <p class="stat-card-detail">+8% vs target</p> </div></div><div className="grid grid-cols-2 gap-4 md:grid-cols-4"> <StatCard icon={IconUsers} label="Users" value="12,408" detail="+1,204 this week" /> <StatCard icon={IconActivity} label="Active now" value="342" detail="peak 412" /> <StatCard icon={IconShoppingBag} label="Orders" value="128" detail="14 pending" /> <StatCard icon={IconCash} label="Revenue" value="$8.4k" detail="+8% vs target" /></div>Revenue
$8.4k
+12.4% vs last week
Error rate
0.42%
-0.18 vs prior
Revenue
$8.4k
+12.4% vs last week
Error rate
0.42%
-0.18 vs prior
<div class="card stat-card"> <p class="stat-card-label">Revenue</p> <p class="stat-card-value">$8.4k</p> <p class="stat-card-trend" data-trend="up" data-intent="positive"> +12.4% vs last week </p></div><div class="card stat-card"> <p class="stat-card-label">Error rate</p> <p class="stat-card-value">0.42%</p> <p class="stat-card-trend" data-trend="down" data-intent="positive"> -0.18 vs prior </p></div><StatCard label="Revenue" value="$8.4k" trend={{ direction: "up", value: "+12.4% vs last week" }}/><StatCard label="Error rate" value="0.42%" trend={{ direction: "down", intent: "positive", value: "-0.18 vs prior" }}/>Per-slot styling React only
Section titled “Per-slot styling ”Error rate
0.42%
last 24h
<StatCard label="Error rate" value="0.42%" detail="last 24h" classNames={{ value: "text-danger", detail: "font-mono" }}/>Custom content
Section titled “Custom content”Error rate
0.42%
last 24 hours
↓ 0.18 vs prior periodError rate
0.42%
last 24 hours
↓ 0.18 vs prior period<div class="card stat-card"> <p class="stat-card-label">Error rate</p> <p class="stat-card-value">0.42%</p> <p class="stat-card-detail">last 24 hours</p> <span class="badge badge-success badge-sm">↓ 0.18 vs prior period</span></div><StatCard label="Error rate" value="0.42%" detail="last 24 hours"> <Badge variant="success" size="sm"> ↓ 0.18 vs prior period </Badge></StatCard>Reference
Section titled “Reference”| Prop | Type | Default |
|---|---|---|
variant |
"default" | "muted" | "primary" | "info" | "success" | "warning" | "danger" |
"default" |
label |
ReactNode |
— |
value |
ReactNode |
— |
detail |
ReactNode |
— |
trend |
StatCardTrend |
— |
icon |
IconProp |
— |
compact |
boolean |
false |
bordered |
boolean |
false |
classNames |
slots | — |
trend is { value, direction?, intent? }: direction is "up" (default), "down" or "flat" and rotates the caret; intent is "positive", "negative" or "neutral" and colours it. They’re independent because a falling error rate is good — omit intent and it follows direction (up → positive).
variant, compact and bordered are the Card modifiers, and the component emits both classes, so a stat card inherits every card surface. Children render below the detail line, which is where a sparkline goes.
There are no sub-parts, so classNames — covering label, value, trend, detail — is the only way to reach the inner elements. Plus native <div> attributes.
Vanilla
Section titled “Vanilla”| Class | Effect |
|---|---|
stat-card |
Flat tile padding: 1rem, 0.25rem gap. Pair with card, with no card-body |
stat-card-label |
text-sm muted medium row, 0.5rem gap for a leading icon |
stat-card-value |
text-2xl bold, tabular figures so digits don’t shift between values |
stat-card-detail |
text-sm muted |
stat-card-trend |
Delta line with a CSS caret, text-sm medium, tabular figures |
stat-card is a modifier on card, not a standalone component — it replaces the card-body rather than sitting inside one, which is why card-compact steps the root here instead of a body.
stat-card-trend reads two attributes: data-trend (up / down / flat) rotates the caret, and data-intent (positive / negative / neutral) colours it. The caret is drawn from borders, so no icon set is involved.
The value picks up the accent under card-primary, card-info, card-success and card-danger — but not card-warning, per Conventions › Tones. A tinted surface signals status, so it stops meaning anything if every tile has one.
Grid layout is yours: the tile bakes in no wrapper. For free-form tiles use Cards; for label/value pairs, a Property list.