"use client"; import { useEffect } from "react"; import { type MotionValue, motion, useSpring, useTransform, } from "framer-motion"; //DOC: https://www.cult-ui.com/docs/components/animated-number 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, onAnimationStart, onAnimationComplete, }: AnimatedNumberProps) { const spring = useSpring(value, { mass, stiffness, damping, }); const display: MotionValue = useTransform(spring, (current) => format ? format(parseFloat(current.toFixed(precision))) : parseFloat(current.toFixed(precision)).toLocaleString(), ); 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 {display}; }