Skip to content

Number Ticker

A number that counts up (or down) to its value once after it appears. The final number is always the text that is read and that is in the server HTML.

Motionv0.1.0experimentalWCAG 2.2 AAView spec

Optional, and kept apart.

Nothing here is included in a project unless you add it, and the plain component it builds on is unchanged. This effect is decoration: it is hidden from screen readers, stands still for visitors who prefer reduced motion, and can be paused. Use Still on a preview to see that version.

12,840
import { NumberTicker } from "@rdloom/react";

export default function NumberTickerBasicExample() {
  return (
    <div className="flex w-full justify-center">
      <NumberTicker value={12840} className="text-4xl font-semibold" />
    </div>
  );
}

Installation

npx rdloom add number-ticker

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/number-ticker.json

Works, but without upgrade tracking.

Usage

import { NumberTicker } from "@rdloom/react";

<div className="flex w-full justify-center">
  <NumberTicker value={12840} className="text-4xl font-semibold" />
</div>

Decimals

99.95
import { NumberTicker } from "@rdloom/react";

export default function NumberTickerDecimalsExample() {
  return (
    <div className="flex w-full justify-center">
      <NumberTicker value={99.95} from={80} decimals={2} className="text-4xl font-semibold" />
    </div>
  );
}

In view

4,500
teams on the plan
import { NumberTicker } from "@rdloom/react";

// Scroll the box: the count starts when the number comes into view.
export default function NumberTickerInViewExample() {
  return (
    <div className="flex w-full justify-center">
      <div className="h-40 w-64 overflow-y-auto rounded-lg border border-[var(--rd-color-border-default)] p-3">
        <div className="flex flex-col items-center gap-3 pt-48 pb-8">
          <NumberTicker value={4500} startWhenInView className="text-3xl font-semibold" />
          <span className="text-sm text-[var(--rd-color-text-muted)]">teams on the plan</span>
        </div>
      </div>
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
valuerequired

The number to count to.

numbernone
from

The number the count starts from.

number0
decimals

Digits after the decimal point, always shown.

number0
duration

Seconds the count takes.

number1.6
startWhenInView

Waits until the number scrolls into view before counting.

booleanfalse
locale

BCP 47 locale for the digits and separators. Defaults to the locale of the visitor.

stringnone
isPaused

Skips the count and shows the final value.

booleanfalse

Accessibility

Role text, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

Not interactive.

Screen readers announce

  • Read once as the final number, never as a stream of changing values

What your code must do

  • The final formatted value is always in the accessible text; the counting digits are hidden from assistive technology so nothing is read number by number
  • The server HTML contains the final value, so it is correct with no JavaScript
  • The count starts after mount only and runs once, for under two seconds by default
  • Visitors who ask for less motion (prefers-reduced-motion), and anything inside rdm-still, see the final value at once
  • Digits use tabular figures so the number does not jitter while it counts
  • Formats with the locale of the visitor through useDefaultLocale, so server and browser agree on first render

Guidelines

Use it when

  • A headline figure on a landing page or dashboard that should feel alive
  • A statistic that appears as the section scrolls into view

Avoid it when

  • Figures people compare closely or copy, where a static number is calmer
  • Values that update often

Don't

  • Counting every number in a table
  • Running the count for many seconds

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-text-default