Number flowPro
A number that rolls each changed digit to its new value: credits, cost, tokens, queue positions. It never counts up from zero on mount, formats with Intl in any locale, and announces politely without flooding screen readers.
On this page
Installation
Usage
import { NumberFlow } from "@/components/ui/chatcn/pro/number-flow"
<NumberFlow value={credits} />
<NumberFlow value={cost} format={{ style: "currency", currency: "USD" }} />
<NumberFlow value={tokens} format={{ notation: "compact" }} suffix=" tokens" />Pass the real value whenever it changes. The first render shows the number as is: count-up animations are on the slop list, so only real changes move. Digits are matched by place value, so 999 to 1,000 rolls the ones, tens and hundreds and fades in the new thousands digit, and digits that did not change stay still.
Examples
Formats and locales
format and locales go straight to Intl.NumberFormat. Separators, currency symbols and the compact K or M are static glyphs that crossfade when they change. Digits roll in the locale's own numbering system, so Arabic digits roll too.
Trend and sizes
With trend="auto" digits roll up when the value grows and down when it shrinks, wrapping through 9 to 0 like an odometer. Force up for counters that only grow. The roll scales with the font, from a 13 px table cell to a 56 px balance.
Props
| Prop | Type | Notes |
|---|---|---|
value | number | Required |
format | Intl.NumberFormatOptions | Currency, compact, percent, fraction digits |
locales | Intl.LocalesArgument | Defaults to the browser locale |
prefix, suffix | ReactNode | Static text around the number, not animated |
trend | "auto" | "up" | "down" | Roll direction. Default auto |
animated | boolean | Default true. Off, the number swaps in place |
duration | number | Roll duration in ms. Default 300 |
announce | boolean | number | Live region updates, at most every 2 s by default. A number sets the interval |
spoken | (formatted) => string | What a screen reader hears |
Accessibility
- The rolling digits are hidden from assistive tech. A visually hidden copy holds the current value, and a polite live region repeats it at most once every 2 s, ending on the latest value. Nothing is announced on mount.
- Turn
announceoff when a parent already announces in words, asqueue-positiondoes. - Selecting and copying the number copies the formatted value, not the digit strips.
- Tabular figures keep every digit the same width, so the number never jitters sideways.
Motion
- Each digit is a strip of three copies of 0 to 9 moved with
transformover 300 ms on the kit's ease out, masked at the top and bottom edge. A run of fast updates interrupts smoothly from wherever the strip is. - Under reduced motion the new value replaces the old with a 150 ms opacity crossfade.