Spring-animated digit counter with transform, opacity, and vertical motion.
npx shadcn@latest add @iconiq/rolling-digits"use client";
import { useEffect, useState } from "react";
import { RollingDigits } from "@/components/ui/rolling-digits";
export function RollingDigitsPreview() {
const [days, setDays] = useState(12);
useEffect(() => {
const interval = window.setInterval(() => {
setDays((current) => (current <= 0 ? 12 : current - 1));
}, 2000);
return () => window.clearInterval(interval);
}, []);
return (
<div className="flex max-w-xl flex-wrap items-center justify-center gap-x-1.5 gap-y-2 text-balance text-center font-medium text-lg leading-snug dark:text-neutral-100">
<span>Early access opens in</span>
<span className="inline-flex translate-y-px items-center align-middle">
<RollingDigits value={days} pad={2} startOnView={false} />
</span>
<span>days.</span>
</div>
);
}valueTarget number to display. The component rounds to the nearest integer before formatting.
Type number
padMinimum digit count. Applied with `padStart` for plain numbers, or through `minimumIntegerDigits` when `locale` is enabled.
Type number
animationDelayMilliseconds between queued value steps when `value` changes faster than the animation can finish.
Type number·Default 80
staggerDeprecated. Seconds between queued steps. Use `animationDelay` in milliseconds instead.
Type number
coalesceUpdatesWhen true, rapid `value` updates replace the pending queue with the latest value instead of stepping through every intermediate update.
Type boolean·Default false
onAnimationCompleteCalled when the displayed value catches up to the latest `value` prop.
Type () => void
ariaLiveControls `aria-live` on the screen-reader layer. `true` maps to `polite`; `false` and `off` disable announcements.
Type boolean | "polite" | "assertive" | "off"·Default true
startOnViewWhen true, playback waits until the component enters the viewport once before animating from zero.
Type boolean·Default true
localeLocale formatting. `locale` uses the runtime default locale, a string sets the locale tag, and an object is passed to `Intl.NumberFormat`. When combined with `pad`, padding is applied through `minimumIntegerDigits`.
Type true | string | Intl.NumberFormatOptions
formatCustom formatter that runs after rounding. Overrides `locale` when both are provided.
Type (value: number) => string
gapPixel gap between rendered characters in the digit row.
Type number·Default 2
directionControls whether incoming digits slide up or down. `dynamic` compares the previous and next digit values.
Type "dynamic" | "up" | "down"·Default dynamic
enterStiffnessSpring stiffness for incoming digit motion.
Type number·Default 170
enterDampingSpring damping for incoming digit motion.
Type number·Default 10
exitStiffnessSpring stiffness for outgoing digit motion.
Type number·Default 170
exitDampingSpring damping for outgoing digit motion.
Type number·Default 15
enterYVertical offset in pixels used when a digit enters.
Type number·Default 32
enterBlurDeprecated. Blur is no longer applied; digit motion uses transform and opacity for Safari-safe rendering.
Type number
enterScaleStarting scale applied when a digit enters.
Type number·Default 0.84
exitScaleEnding scale applied when a digit exits.
Type number·Default 0.84
classNameMerged onto the outer inline-flex span that wraps the readable and visual layers.
Type string
digitClassNameMerged onto each animated digit cell wrapper for per-digit styling.
Type string
Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.
Dependencies: motion.
Contact
Additionally, if you find any bug or issue, feel free to raise an issue.