Sliding Number

A number whose digits roll to their new value, like an odometer.

2.025
"use client"

import * as React from "react"
import { SlidingNumber } from "@animate-ui/react/primitives/texts/sliding-number"
import { RefreshIcon } from "@hugeicons/core-free-icons"
import { HugeiconsIcon } from "@hugeicons/react"

import { Button } from "@/components/ui/button"

export default function SlidingNumberDemo({
  number = 2025,
  fromNumber = true,
  padStart = true,
  decimalSeparator = ",",
  decimalPlaces = 0,
  thousandSeparator = ".",
  delay = 0,
}: {
  number?: number
  fromNumber?: boolean
  padStart?: boolean
  decimalSeparator?: string
  decimalPlaces?: number
  thousandSeparator?: string
  delay?: number
}) {
  const [run, setRun] = React.useState(0)

  return (
    <div className="flex flex-col items-center gap-6">
      <SlidingNumber
        key={`${run}-${delay}-${fromNumber}`}
        number={number}
        fromNumber={fromNumber ? 0 : undefined}
        padStart={padStart}
        decimalSeparator={decimalSeparator}
        decimalPlaces={decimalPlaces}
        thousandSeparator={thousandSeparator}
        delay={delay}
        className="text-4xl font-semibold"
      />
      <Button variant="outline" size="sm" onClick={() => setRun((n) => n + 1)}>
        <HugeiconsIcon icon={RefreshIcon} strokeWidth={2} data-icon="inline-start" />
        Replay
      </Button>
    </div>
  )
}

Installation

npm install @animate-ui/react motion
pnpm add @animate-ui/react motion
yarn add @animate-ui/react motion
bun add @animate-ui/react motion

Usage

import { SlidingNumber } from '@animate-ui/react/primitives/texts/sliding-number';

export function Price({ value }: { value: number }) {
  return <SlidingNumber number={value} thousandSeparator="," />;
}

Animation

  • Each digit sits on a wheel that springs to its new value (stiffness: 200, damping: 20, mass: 0.4), straight through the digits in between: going from 9 to 0, it rolls back through 8, 7…
  • With fromNumber, the number counts to number on a spring (stiffness: 90, damping: 50), every digit rolling on the way; a new number then counts on from the current value. Without it, the digits roll straight to their new value.
  • Digits are positioned in percentages of their own height: no measuring, right on the first frame and when the font size changes. Counting doesn't re-render React per frame.
  • <AnimateUIProvider tempo> paces the default springs.
  • Under reduced motion, the digits change without rolling.
  • Screen readers read the number once, not every rolled digit.

API Reference

SlidingNumber

PropTypeDefault
number
number-
fromNumber?
number-
onNumberChange?
(number: number) => void-
padStart?
booleanfalse
decimalSeparator?
string'.'
decimalPlaces?
number0
thousandSeparator?
string-
transition?
SpringOptions{ stiffness: 200, damping: 20, mass: 0.4 }
delay?
number0
initiallyStable?
booleanfalse
inView?
booleanfalse
inViewMargin?
string'0px'
inViewOnce?
booleantrue
...props?
Omit<HTMLMotionProps<'span'>, 'children'>-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/18/2026

On this page