Data Display & Media
Stat Card
A single headline figure for a dashboard: what it measures, the number, and how it moved. Lay several out with a CSS grid, and set tone to colour the icon and the change.
Preview
Section titled “Preview”<div
style="
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
"
>
<nana-stat-card label="Total revenue" value="KSh 45,231.89" change="20.1">
<nana-icon slot="icon" name="payments"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Subscriptions" value="+2,350" change="180.1">
<nana-icon slot="icon" name="people"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Sales" value="+12,234" change="19">
<nana-icon slot="icon" name="credit_card"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Active now" value="+573" hint="+201 since last hour">
<nana-icon slot="icon" name="show_chart"></nana-icon>
</nana-stat-card>
</div> Installation
Section titled “Installation”Install the package for a versioned dependency:
npm install @nana-tec/ui-componentsOr copy the source in and own it:
npx @nana-tec/ui add stat-cardReact projects get the stats-cards block instead, which lays out a grid of
cards from an array:
npx @nana-tec/ui add stats-cardsSvelte projects get the stats-cards block instead, which lays out a grid of
cards from an array:
npx @nana-tec/ui add stats-cardsAll three format the change the same way — the rule lives in
headless/stats-cards.
import "@nana-tec/ui-components/stat-card";<nana-stat-card label="Total revenue" value="KSh 45,231.89" change="20.1"> <nana-icon slot="icon" name="payments"></nana-icon></nana-stat-card>value is shown as given, so format it yourself — currency, separators, a
leading +. change is a signed percentage and is formatted for you:
20.1 reads as +20.1%, -4 as −4%.
The detail line
Section titled “The detail line”The line under the figure follows one rule:
| You set | The line reads |
|---|---|
change | +20.1% from last month |
change and comparison | +20.1% from last week |
change and hint | +20.1% since yesterday |
hint only | +201 since last hour |
| neither | nothing — the line is left out |
<div
style="
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
"
>
<nana-stat-card
label="Orders"
value="1,204"
change="8"
comparison="from last week"
></nana-stat-card>
<nana-stat-card
label="Active now"
value="+573"
hint="+201 since last hour"
></nana-stat-card>
<nana-stat-card label="Members" value="3,980"></nana-stat-card>
</div> tone colours the icon and the change. It does not pick itself from the sign of
the change: a rise in cancellations is bad news, so you decide.
<div
style="
display: grid;
gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
"
>
<nana-stat-card label="Neutral" value="1,024" change="12">
<nana-icon slot="icon" name="trending_up"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Primary" value="1,024" change="12" tone="primary">
<nana-icon slot="icon" name="trending_up"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Success" value="1,024" change="12" tone="success">
<nana-icon slot="icon" name="trending_up"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Warning" value="1,024" change="12" tone="warning">
<nana-icon slot="icon" name="trending_up"></nana-icon>
</nana-stat-card>
<nana-stat-card label="Danger" value="1,024" change="-8" tone="danger">
<nana-icon slot="icon" name="trending_up"></nana-icon>
</nana-stat-card>
</div> Accessibility
Section titled “Accessibility”Each card is a description list: the label is the term, and the figure and its detail line are its descriptions, so a screen reader announces them together. The icon is decorative and hidden from assistive technology. Tone is never the only signal — the change keeps its sign.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
change | change | number | undefined | — | Signed percentage change over the comparison window, e.g. 12.5 or -3 |
comparison | comparison | string | 'from last month' | What change is measured against |
hint | hint | string | undefined | — | Replaces the comparison text, e.g. +201 since last hour |
label | label | string | '' | What the figure measures |
tone | tone | StatCardTone | 'neutral' | Colours the icon and the change |
value | value | string | '' | The headline figure, already formatted |
Slots
| Slot | Description |
|---|---|
icon | A small glyph shown beside the label, tinted by tone |
CSS parts
| Part | Description |
|---|---|
::part(base) | The card |
::part(label) | The row holding the label and icon |
::part(icon) | The icon wrapper |
::part(value) | The headline figure |
::part(detail) | The line under the figure |
::part(change) | The formatted change inside the detail line |
CSS custom properties
| Property | Description |
|---|---|
--nana-stat-card-bg | Card background |
--nana-stat-card-border | Card border colour |
--nana-stat-card-radius | Card corner radius |
--nana-stat-card-padding | Card padding |