Stat

One number that matters, with what it measures and how it moved: the headline numbers of a dashboard, also called a KPI. Specification: docs/components/stat.md

Basics

A .canon-stat: a .canon-stat-label (what is measured, with its period), a .canon-stat-value (the number, formatted by your app), and optionally a .canon-stat-change and a .canon-stat-description. It is plain, with no frame of its own: the Card, the row or the page around it frames it.

Revenue this month

$48,210

Up 12% from last month

Goal: $50,000

The change

Your app writes the whole phrase, in the reader's language, with the direction in words: the arrow is decoration. data-direction (up, down, flat) draws the arrow; data-intent says whether the move is good (success), bad (danger), near a limit (warning) or worth noticing (info). The two are separate: an error rate going up is bad, a headcount going up is neither.

Revenue this month

$48,210

Up 12% from last month

Error rate

2.4%

Up 0.8 points since yesterday

Avg. response time

1.2 s

Down 0.3 s this week

Storage used

92%

Up 40%: near your plan's limit

Team members

38

3 more than last quarter

Open tickets

14

No change since Monday

A row of stats

.canon-stats lays stats side by side, as many columns as fit (each at least 12rem), wrapping onto more rows. Name it (role="group", aria-label) when the stats share a context the page doesn't give. data-lines draws a line between the stats of a row. Here in a Card, which frames them; drag the frame's corner to see them wrap.

This month

Revenue

$48,210

Up 12% from last month

New customers

126

Up 8 from last month

Churn

3.1%

Up 0.4 points

Overdue invoices

8

Same as last month

Sparkline

A .canon-stat-chart holds a sparkline your app draws: an inline <svg> with preserveAspectRatio="none" that strokes and fills with currentColor. Canon stretches it to the stat's width, keeps its lines their drawn width and colors it: quiet grey, or the change's color at 60%. It is aria-hidden="true" when the change already says the trend. Canon doesn't draw charts.

Signups, last 30 days

1,284

Up 18% from the 30 before

Failed payments

37

Up 9 from the 30 before

Active sessions

412

Peak at 14:00

Size

data-size on the stat, the row or a container: the value 24 / 30 / 36px, the rest to match. A headline stat is a bigger size beside smaller ones, not a different kind of stat.

sm

$48,210

Up 12% from last month

md

$48,210

Up 12% from last month

lg

$48,210

Up 12% from last month

Loading and empty

While the value loads: aria-busy="true" on the stat (or the row) and a Skeleton block in the value. No value: an empty .canon-stat-value shows a dash, which screen readers hear as "Not set". How fresh the number is goes in the description, in your words.

Revenue this month

Net promoter score

Not enough answers yet

Active users

2,931

Up 2% since yesterday

Updated 3 hours ago

Edge cases

A long label and change wrap; a value keeps its digits together and wraps only at spaces. Right to left, the stat starts on the right and the arrows mirror, as time runs the other way.

Average time from a ticket being opened to its first reply, business hours only

4 h 12 min

Down 38 minutes from the previous four weeks, across every queue

Annual recurring revenue

$12,480,915.50

الإيرادات هذا الشهر

٤٨٬٢١٠ $

ارتفاع ١٢٪ عن الشهر الماضي