Stat
One figure written large, with a label over it, a unit after it and a badge beside it.
Use it for the one number a panel is about: storage used, a response time, words written this month. The badge on the far side of the row says how the reading stands, such as "31.6 GB free" or "inside budget".
It shows a number and nothing else. It does not draw a trend, a sparkline or a target; put the chart that goes with the number under it, in the same panel.
For a metric with a trend, a sparkline or progress towards a target, use KPI. For a number that rolls to its new value as it changes, put a NumberFlow inside StatValue.
Installation
Copy the folder into components/ui, where you can edit it. It needs only the cn helper.
components/ui/stat/
├── Stat.vue
├── StatContent.vue … StatBadge.vue
└── index.tsUsage
<script setup lang="ts">
import { Stat, StatBadge, StatContent, StatLabel, StatUnit, StatValue } from "@/components/ui/stat";
</script>
<template>
<Stat>
<StatContent>
<StatLabel>Response time</StatLabel>
<StatValue>240<StatUnit>ms</StatUnit></StatValue>
</StatContent>
<StatBadge>60 ms inside budget</StatBadge>
</Stat>
</template>Composition
<Stat>
<StatContent>
<StatLabel />
<StatDescription />
<StatValue>
<StatUnit />
</StatValue>
</StatContent>
<StatBadge />
</Stat>- StatContent: the label and the value, stacked. Use it on its own, without Stat round it, for a figure with no badge.
- StatLabel: what is measured, in a quiet line over the value. weight="medium" sets it heavier, for a figure that stands on its own rather than under a panel's title.
- StatDescription: what the reading means, in words, under the label: "Answering slowly".
- StatValue: the figure. size is sm, md or lg, from 2xl to 4xl; the default is lg.
- StatUnit: the unit after the number, written inside StatValue. It takes its size and its gap from the value.
- StatBadge: how the reading stands, in a pill on the trailing side of the row.
Sizes
size on StatValue sets the figure at 2xl, 3xl or 4xl, and the unit is sized to match.
API Reference
StatLabel
StatValue
Every part also takes the attributes of the element it renders, and a class.
Notes
In a row and on its own
Inside Stat, the value is set with no leading, so the foot of the number lines up with the foot of the badge at the bottom of the row. A StatContent used on its own keeps the value's line height, which is what text beside it expects.
Changing values
Give Stat aria-live="polite" when the number changes as somebody uses the chart beside it, so a screen reader reads the new figure without cutting in on anything else.
Server rendering
It holds no state and handles no events, so it renders the same on the server as in the browser.