Stat

One headline number with its label, counting up into view, on its own, in a card or in a banner.

Stat shows one number that makes a case: total value, users, yield. It renders a description list, so the label and value stay paired for assistive technology whichever one is on top. Stat has no surface of its own; put it in a Card for the tile.

import { Stat } from '@base-org/bds-web/product/stat';

<Stat value={3} prefix="$" suffix="B+" label="Supplied across Base markets" />;

Variants

Default

One number, the value above its label, with no surface. Use it in a hero or anywhere a box would be one too many. A numeric value counts up as it scrolls into view; see Number flow.

Supplied across Base markets
$3B+
<Stat value={3} prefix="$" suffix="B+" label="Supplied across Base markets" />

The label leads and a display-size value sits at the bottom. Use it for the one number a section is about.

Average yield
4.45%
Average USD stablecoin yield across Base lending markets, prior to any incentives.
<Stat variant="featured" value={4.45} suffix="%" format={{ minimumFractionDigits: 2 }} label="Average yield" footnote="Average USD stablecoin yield across Base lending markets, prior to any incentives." />

Examples

In a card

Wrap a Stat in a Card for a tile, and lay tiles out with Card Group. The Stat fills the card, so in a tall card the value stays at the top and the label at the bottom.

Average yield
4.45%
Lenders
200K+
Borrowers
115K+
<Card.Group columns={2}>
<Card>
  <Stat variant="featured" value={4.45} suffix="%" format={{ minimumFractionDigits: 2 }} label="Average yield" />
</Card>
<div className="grid gap-4">
  <Card><Stat value={200} suffix="K+" label="Lenders" /></Card>
  <Card><Stat value={115} suffix="K+" label="Borrowers" /></Card>
</div>
</Card.Group>

A row of centred stats with no surface, as in base.org's page heroes: two columns on mobile and one per stat from md, with a wide gap. align="center" centres each stat and labelStyle="mono" gives the small uppercase Base Sans Mono label; tiles keep the default sans label.

Supplied
$3B+
Lenders
200K+
Borrowers
115K+
<div className="grid grid-cols-2 gap-x-6 gap-y-10 md:grid-cols-3 md:gap-16">
<Stat align="center" tone="neutral" labelStyle="mono" value={3} prefix="$" suffix="B+" label="Supplied" />
<Stat align="center" tone="neutral" labelStyle="mono" value={200} suffix="K+" label="Lenders" />
<Stat align="center" tone="neutral" labelStyle="mono" value={115} suffix="K+" label="Borrowers" />
</div>

Number flow

Pass value as a number and Stat counts it up from 0 with NumberFlow when it is 20% in view, once. prefix and suffix carry the units, and format takes number format options such as fraction digits. Under reduced motion, or with animated={false}, the real figure shows straight away. A string value renders as is, for a figure that isn't a plain number.

Builders on Base
12,000+
Settlement
T+0
<Stat value={12000} suffix="+" label="Builders on Base" />
<Stat value="T+0" label="Settlement" />

Tone

brand colours the value brand blue; neutral uses the primary foreground for pages where blue would compete with the artwork.

Supplied
$3B+
Supplied
$3B+
<Stat tone="brand" value={3} prefix="$" suffix="B+" label="Supplied" />
<Stat tone="neutral" value={3} prefix="$" suffix="B+" label="Supplied" />

Trend and footnote

trend sits beside the value for a short change, such as "+12%". footnote is small print under the value: a period, a source, a definition.

Builders on Base
12,000++12%
Last 30 days
<Stat value={12000} suffix="+" label="Builders on Base" trend="+12%" footnote="Last 30 days" />

When to use

Use Stat for a headline number: on its own, in a row of two to four cards, or in a banner, on a product surface or a base.org page.

Use something else when:

  • The number has a chart or a trend over time. Use Metric Card.
  • The tile has a title and body copy rather than a number. Use Card with its own slots.

Usage

Do

Pass the number and its units separately (value={3} prefix="$" suffix="B+") so it can count up. Round to the precision that supports the claim.

Don't

Animate the number yourself inside value. Stat's count-up already runs once, respects reduced motion, and settles on the real figure.

  • Keep labels to a few words in sentence case; the footnote holds the qualification.
  • One featured stat per row at most.
  • For a tile, wrap the Stat in a Card rather than giving it a background or padding yourself, so stats and content cards share one surface. A banner needs no surface.

Props

PropTypeDefault
labelrequired

What the number measures.

TypeReactNodeDefault—
valuerequired

The number. A `number` counts up from 0 when the stat scrolls into view;

TypeReactNodeDefault—
alignType"center" | "start" | nullDefaultstart
animated

Count a numeric value up from 0 when it scrolls into view. Defaults to

TypebooleanDefaulttrue
footnote

Small print under the value, such as a source, period or definition.

TypeReactNodeDefault—
format

Number format options for a numeric value, such as fraction digits.

TypeanyDefault—
labelStyle

`default` is the sans label of a stat tile. `mono` is the small uppercase

Type"default" | "mono" | nullDefaultdefault
prefix

Text before a numeric value, such as "$".

TypestringDefault—
suffix

Text after a numeric value, such as "B+" or "%".

TypestringDefault—
toneType"brand" | "neutral" | nullDefaultbrand
trend

A short change indicator beside the value, such as "+12%".

TypeReactNodeDefault—
variantType"default" | "featured" | nullDefaultdefault

Accessibility

Stat renders a dl: the label is the dt, and the value (and footnote) are dds, so screen readers read "label, value" however the two are arranged. A numeric value's rolling digits are hidden from assistive technology, and a visually hidden copy of the final figure (with its prefix and suffix) is read instead, so screen readers get the real number even before the count-up runs. trend is part of the value's dd; write it so it reads well after the number ("+12%", not an arrow alone). Colour carries no meaning on its own: a brand or neutral tone changes emphasis, not sense.