CountUp
A number that counts up to its final value when it scrolls into view.
CountUp renders a number that counts up to its final value the first time it scrolls into view. The final value is the element's real text, so with JavaScript off, under prefers-reduced-motion: reduce, or for a value with no number it renders as a plain static number — the sweep is a pure enhancement, never a gate. Duration and easing are token-backed (--duration-xl / --ease-out), and tabular-nums holds the width steady so the surrounding layout does not jitter as the digits change.
It has one visual appearance — the only input is the value it counts to, and it parses the number out of whatever string it wraps (4,800+, 98%, $2M), re-appending the prefix, suffix, and thousands grouping while counting.
CountUp
Use when: A proof-point number that should animate up as the reader reaches it — a stat bar, a metric callout. The motion draws the eye to the figure.
Don't: A static count badge or a live-updating tally — that's Counter.
<CountUp>4,800+</CountUp>Counter
Use when: A small static numeric indicator with tone colors — an unread count, a quantity chip. No animation.
Don't: The number should sweep up into view — that's CountUp.
<Counter value={12} />Use it for
- A proof-point stat bar (the first adopter is the
stats_barblueprint viacontentMotion: count-up) - A single metric callout where the count-up motion reinforces the figure
Blueprints never place CountUp directly — a block sets contentMotion: count-up on its section and the shared BlockContentMotion dispatcher wraps each number.
Import
import { CountUp } from '@brikdesigns/bds';Default
The value shapes it handles — bare integer, grouped thousands, percentage, unit suffix, currency prefix — are all the same component reading a different string:
Accessibility
- The count fires once, when at least half the number is in view. Under
prefers-reduced-motion: reduceit never runs — the static final number is already the DOM text, so there is no un-gated motion path. - The number is content, not decoration. The sweep only transiently changes the text, so assistive tech announces the final value.
- CountUp provides no accessible name of its own; it is a number inside surrounding content (a stat's caption, a section heading) that names it.
CSS Override API
| Variable | Default | Purpose |
|---|---|---|
--bds-count-up-duration | var(--bds-duration-xl) (500ms) | Length of the count sweep |
--bds-count-up-ease | var(--bds-ease-out) | Easing curve the sweep follows |
API
| Prop | Type | Default |
|---|---|---|
children | ReactNode | — (required — the final value; the number counts up to it) |
Inherits all native <span> attributes (className, style, data-*, …).