Skip to content
New

Number Roll

A number whose digits roll to their value, formatted for any locale: counters, prices, live stats.

Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M

Installation

Terminal
npx rasengan-ui add number-roll

Or with the shadcn CLI, from the registry:

Terminal
npx shadcn@latest add https://ui.rasengan.dev/r/base/number-roll.json

It brings rasengan-motion with it. Put <MotionScript /> in <head> and <MotionProvider> around the app once.

Usage

app/usage.tsx
import { NumberRoll } from "@/components/ui/number-roll";
 
export function Usage() {
  return (
    <NumberRoll
      value={4200000}
      format={{ style: "currency", currency: "USD", notation: "compact" }}
      locale="en-US"
    />
  );
}

format takes the options of Intl.NumberFormat: currencies, percentages, units, compact notation, decimals. The digits roll in when the number comes into view, then on every change.

Live values

Each digit keeps its place when the number grows, so 9 to 10 rolls the units and adds a ten. With live="polite", screen readers hear the new value.

36,00 €per month, 3 seats

Villages

The columns slide with the village's slow duration and ease-out, one after another by its stagger: Kusa's overshoot and settles, Iwa's are short and exact.

Konoha · light
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Konoha · dark
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Kiri · light
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Kiri · dark
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Iwa · light
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Iwa · dark
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Kusa · light
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M
Kusa · dark
Sites shipped
12,480
Uptime
99.97%
Raised
$4.2M

Reduced motion

With reduced motion, ?motion=off, ?motion=final or a scope at data-motion-intensity="0", the number is simply there and changes without rolling.

Accessibility

  • Screen readers read the formatted value once ($4.2M, 99.97%); the digit columns are hidden from them.
  • live="polite" announces changes; leave it off for numbers that change on their own, or it gets noisy.

Weight

About 2.8 kB gzip beyond cn(). Nothing from Motion: the columns move with CSS transitions timed by the village's tokens.

API reference

NumberRoll renders a span and takes its props and className, and:

PropTypeDefault
valuenumber—
formatIntl.NumberFormatOptions—
localestringthe browser's
trigger"view" | "mount""view"
live"off" | "polite""off"