Skip to main content
Clever Ops

Number Odometer

Multi-digit odometer where every digit rolls inside its own masked column, settling right to left like a meter, with prefix, suffix, and decimal support.

Preview & code

Loading Number Odometer preview

Installation

pnpm dlx shadcn@latest add @cleverui/number-odometer

Requires the @cleverui registry in your components.json, a one-off, two-line setup.

Usage

tsx
import { NumberOdometer } from '@/components/ui/number-odometer'
Exampletsx
import { NumberOdometer } from '@/components/ui/number-odometer'

export default function NumberOdometerDemo() {
  return (
    <div className="mx-auto flex min-h-[360px] max-w-3xl flex-col items-center justify-center gap-10 px-6 py-16">
      <div className="w-full max-w-md border border-border/60 bg-card px-6 py-8 sm:px-8">
        <p className="font-mono text-[11px] uppercase tracking-[0.2em] text-muted-foreground sm:text-xs">
          Pipeline · live board
        </p>
        <p className="mt-4 text-4xl sm:text-5xl">
          <NumberOdometer value={1284500} prefix="$" locale="en-US" />
        </p>
        <p className="mt-3 text-sm leading-relaxed text-muted-foreground">
          Qualified ARR in Meridian&apos;s enterprise queue this quarter.
        </p>
      </div>

      <div className="flex w-full max-w-md flex-wrap items-end justify-between gap-6 border-t border-border/60 pt-8">
        <div>
          <p className="font-mono text-[11px] uppercase tracking-[0.2em] text-muted-foreground">
            Uptime
          </p>
          <p className="mt-2 text-3xl">
            <NumberOdometer value={99.98} decimals={2} suffix="%" duration={0.9} />
          </p>
        </div>
        <div className="text-right">
          <p className="font-mono text-[11px] uppercase tracking-[0.2em] text-muted-foreground">
            Seats filled
          </p>
          <p className="mt-2 text-3xl">
            <NumberOdometer value={4821} suffix="+" duration={0.7} />
          </p>
        </div>
      </div>
    </div>
  )
}

API reference

NumberOdometer accepts the following props.

PropTypeDefaultDescription
value*numbertarget number the columns roll to
decimalsnumber0fraction digits rendered after a static decimal point
prefixstring''static glyph before the digits, e.g. '$'
suffixstring''static glyph after the digits, e.g. '+'
durationnumber0.8seconds for one column's roll; columns stagger right to left
localestring'en-US'Intl locale for grouping separators rendered as static glyphs

…plus everything from React.HTMLAttributes<HTMLSpanElement>: className, event handlers, aria attributes and the rest pass straight through.

Frequently asked questions

How do I install the Number Odometer component?

Register the @cleverui registry in your components.json ("@cleverui": "https://cleverops.com.au/r/{name}.json"), then run `npx shadcn@latest add @cleverui/number-odometer`. The shadcn CLI copies the source into your project, you own the code from that point. You can also copy the source directly from this page.

What dependencies does Number Odometer require?

Number Odometer uses motion on top of React and Tailwind CSS. You don't need to install it manually, the shadcn CLI resolves and installs npm dependencies automatically when you add the component.

Can I theme Number Odometer to match my brand?

Yes. The component is styled entirely with Tailwind utilities over standard design tokens (primary, background, muted, border), so it inherits your existing shadcn/ui theme automatically. Change your CSS variables and the component follows, no source edits needed for palette, radius, or fonts.

Want this built for you?

CleverUI is built by the Clever Ops web team. If you'd rather ship a hand-coded, fast, custom website than assemble one, we build them for Australian businesses every week.

Explore web development services