MotionNumber · MotionText
A number whose places roll like wheels, including places that appear or disappear.
WebReact NativeNumbers and text
Try it
Preparing the example…
Shortest usage
<MotionNumber value={count} />
<MotionNumber value={total} mode="roll" intl locale="en-US"
format={{ style: 'currency', currency: 'USD' }} />
<MotionText>{status}</MotionText>What it handles for you
- Carries:
999 → 1,000rolls every changed place the same way, like an odometer. - Places that appear or disappear roll in or out of their own column instead of popping.
- Separators, signs and currency symbols fade in and out with the place they belong to.
- Remaining places slide to their new positions while they roll, so the number never splits.
- A new value in the middle of a motion continues from exactly what is on screen.
- Formatting never requires
Intl: pass text or aformatfunction, or opt in withintl.
Use it for
- A cart total that changes as items are added.
- A live counter or score.
- A dashboard figure that refreshes every few seconds.
Props
MotionNumber
| Prop | Type | Default | Description |
|---|---|---|---|
value | number | bigint | string | —required | The number, or caller-formatted numeric text. |
mode | 'replace' | 'roll' | 'replace' | replace moves each changed place one step; roll passes through the digits in between. |
direction | 'auto' | 'digit' | 'up' | 'down' | 'auto' | auto follows the change in size so carries roll one way; digit compares each place on its own. |
stagger | number | 45 | Milliseconds between changed places, from the units outward. The whole ripple is bounded. |
format | (value) => string | Intl.NumberFormatOptions | A function that returns the text to show, or Intl.NumberFormat options (with intl). | |
intl | boolean | false | Use the built-in Intl.NumberFormat. Off by default so no runtime needs Intl. |
locale | string | string[] | Locale for intl. | |
prefix | string | Text before the number. | |
suffix | string | Text after the number. | |
transition | Transition | spring | A timing curve { duration, easing } or a spring { tempo: 'spring', spring }. Springs keep their momentum when interrupted. |
onMotionComplete | (value) => void | Runs with the value once the places have settled. |
MotionText
| Prop | Type | Default | Description |
|---|---|---|---|
children | ReactNode | The text to show. | |
as | element | 'span' | The element to render. |
transition | Transition | spring | A timing curve { duration, easing } or a spring { tempo: 'spring', spring }. Springs keep their momentum when interrupted. |
onMotionComplete | (text) => void | Runs when the motion settles. |
Other props go to the rendered element, so className, style and event handlers work as usual.
Web and React Native
On the web each place is a small stack of glyphs played by the Web Animations API, and the text stays selectable. MotionText animates any text: numeric text rolls per place, other text swaps.
On React Native the number stays a real Text for layout, selection and accessibility, including wrapping and numberOfLines; the glyphs move on the native driver.
Used in these examples
- Checkout summaryQuantities, line totals and the total roll as the cart changes; the coupon notice enters and leaves; paying takes a deliberate hold.
MotionListMotionNumberMotionPresenceMotionHold - InboxFilter tabs with live counts, rows you can swipe away and a list that closes the gap.
MotionHighlightMotionListMotionSwipeMotionNumber