All components
Animated Number
data-displayNumber component with smooth counting animations and customizable formatting
responsive · 380px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/animated-number.jsonUsage
"use client";
import { useState } from "react";
import { AnimatedNumber } from "@/registry/cult-ui/animated-number";
export default function Demo() {
const [value, setValue] = useState(1234);
const targets = [0, 999, 1234, 42000, 1000000];
return (
<div className="w-full max-w-sm mx-auto flex flex-col items-center gap-6 p-8">
<div className="text-5xl font-bold text-white tabular-nums">
<AnimatedNumber
value={value}
mass={0.8}
stiffness={75}
damping={15}
precision={0}
format={(n) => n.toLocaleString()}
/>
</div>
<div className="flex flex-wrap gap-2 justify-center">
{targets.map((t) => (
<button
key={t}
onClick={() => setValue(t)}
className="px-3 py-1.5 text-sm rounded-lg bg-neutral-800 text-white hover:bg-neutral-700 transition-colors"
>
{t.toLocaleString()}
</button>
))}
</div>
</div>
);
}Component source
"use client"
import { useEffect } from "react"
import { motion, MotionValue, useSpring, useTransform } from "motion/react"
interface AnimatedNumberProps {
value: number
mass?: number
stiffness?: number
damping?: number
precision?: number
format?: (value: number) => string
onAnimationStart?: () => void
onAnimationComplete?: () => void
}
export function AnimatedNumber({
value,
mass = 0.8,
stiffness = 75,
damping = 15,
precision = 0,
format = (num) => num.toLocaleString(),
onAnimationStart,
onAnimationComplete,
}: AnimatedNumberProps) {
const spring = useSpring(value, { mass, stiffness, damping })
const display: MotionValue<string> = useTransform(spring, (current) =>
format(parseFloat(current.toFixed(precision)))
)
useEffect(() => {
spring.set(value)
if (onAnimationStart) onAnimationStart()
const unsubscribe = spring.on("change", () => {
if (spring.get() === value && onAnimationComplete) onAnimationComplete()
})
return () => unsubscribe()
}, [spring, value, onAnimationStart, onAnimationComplete])
return <motion.span>{display}</motion.span>
}Dependencies
motion
Source: Cult UI