Easily animate numbers.
1'use client';
2import { cn } from '@/lib/utils';
3import { motion, SpringOptions, useSpring, useTransform } from 'motion/react';
4import { useEffect } from 'react';
5
6export type AnimatedNumberProps = {
7 value: number;
8 className?: string;
9 springOptions?: SpringOptions;
10 as?: React.ElementType;
11};
12
13export function AnimatedNumber({
14 value,
15 className,
16 springOptions,
17 as = 'span',
18}: AnimatedNumberProps) {
19 const MotionComponent = motion.create(as as keyof JSX.IntrinsicElements);
20
21 const spring = useSpring(value, springOptions);
22 const display = useTransform(spring, (current) =>
23 Math.round(current).toLocaleString()
24 );
25
26 useEffect(() => {
27 spring.set(value);
28 }, [spring, value]);
29
30 return (
31 <MotionComponent className={cn('tabular-nums', className)}>
32 {display}
33 </MotionComponent>
34 );
35}
36