Stat
A figure with its name: a label, a value, and, when it matters, how the
value moved and against what. One tile answers “how many”; a Stat.Group
lines several up as the row a page leads with, before the charts that
explain them.
Import
import { Stat } from "@photon-ai/pho-ui/components/stat";
Basic
label names the figure, value is the figure already formatted (the tile
does no rounding of its own), delta says how it moved and note what it
moved against. The value takes the display size in the font’s proportional
figures; label and note stay in the UI inks, so the number is the only loud
thing.
<Stat
label="Messages"
value="12,001"
delta={30}
note="vs. 9,231 the week before"
/>
Group
Stat.Group lays tiles in one framed row with a hairline between each. Every
tile takes an equal share and never gets narrower than 12rem; past that the
row wraps, the hairlines follow, and a tile alone on the last line stretches
across it, so five tiles read as one card at any width. A long label
truncates rather than pushing its delta off the tile.
<Stat.Group aria-label="Traffic this week">
<Stat label="Visitors" value="20.8K" delta={-42} note="vs. 36.2K prior" />
<Stat label="Page views" value="151K" delta={-23} note="vs. 196K prior" />
<Stat label="Sessions" value="35.2K" delta={-33} note="vs. 52.8K prior" />
<Stat
label="Session duration"
value="8m 32s"
delta={24}
note="vs. 6m 52s prior"
/>
<Stat
label="Bounce rate"
value="23%"
delta={-27}
deltaGood="down"
note="vs. 31% prior"
/>
</Stat.Group>
Which way is good
A number delta is a percentage change, rendered signed with one decimal and
an arrow. A string renders as written, and its leading sign sets the arrow;
pass deltaDirection when the string can’t say. The badge’s ink says whether
the move is good news, and deltaGood names the good direction: up by
default, down for a bounce rate or a failure count, none when a change is
just information. A flat delta has no arrow and no verdict.
<Stat label="Active users" value="300" delta="+30%" />
<Stat label="Failed deliveries" value="20" delta={-12} deltaGood="down" />
<Stat label="Response ratio" value="1:1" delta="-10%" deltaGood="none" />
<Stat label="Numbers" value="4" delta={0} />
Inside a card
A tile has no chrome of its own, so it sits in any card. For a row inside a
card, variant="plain" keeps the hairlines between tiles and drops the
frame. Card.Root drops its matching inset when the group is the first or
last child, so the tiles run edge to edge.
Activity
<Card.Root>
<Card.Header>
<Card.Title>Activity</Card.Title>
</Card.Header>
<Stat.Group variant="plain" aria-label="Activity this week">
<Stat label="Active users" value="300" delta={30} />
<Stat label="Active chats" value="150" delta={30} />
<Stat label="Response ratio" value="1:1" delta={-10} deltaGood="none" />
</Stat.Group>
</Card.Root>
Props
Stat renders a <div> and forwards every div attribute.
- label —
ReactNode(required) — what the figure counts - value —
ReactNode(required) — the figure, already formatted - delta —
number·string— a percentage change (signed, one decimal) or a preformatted string - deltaDirection —
up·down·flat— the arrow, when the string’s sign can’t say; derived otherwise - deltaGood —
up·down·none(defaultup) — the direction that reads as good news - note —
ReactNode— what the delta is against
Stat.Group renders a <div role="group">; give it an aria-label.
- variant —
card·plain(defaultcard) — framed as a card of its own, or hairlines only
Accessibility
- Semantics — a tile is plain text in reading order: label, delta,
value, note. A group is
role="group"; name it witharia-labelso the row is announced as one thing. - Direction is never colour alone — the arrow travels with the ink, and the sign is in the text.
Best practices
- Format the value on the page, in the unit the reader uses:
12,001,8m 32s,1:1. The tile shows what it is given. - Name the comparison in
note(“vs. 36.2K prior”) whenever a delta is shown; a percentage with nothing behind it is a guess. - Set
deltaGoodby what the figure means, once, where the tile is written. A drop in failures is green. - Keep a group to the figures the page is about, five or fewer. More belong in a table.