/** * ============================================================================= * QWHPI — Quebec Weekly Housing Price Index * Author : Simon-Pierre Boucher * Contact : contact@spboucher.ai * File : web/components/CountUp.tsx * Purpose : Animated number count-up (easeOut, reduced-motion aware). * ============================================================================= */ "use client"; import { useEffect, useRef, useState } from "react"; export default function CountUp({ value, decimals = 1, duration = 1100, prefix = "", suffix = "", }: { value: number; decimals?: number; duration?: number; prefix?: string; suffix?: string; }) { const [display, setDisplay] = useState(0); const raf = useRef(0); useEffect(() => { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setDisplay(value); return; } const t0 = performance.now(); const tick = (t: number) => { const p = Math.min(1, (t - t0) / duration); const eased = 1 - Math.pow(1 - p, 3); setDisplay(value * eased); if (p < 1) raf.current = requestAnimationFrame(tick); }; raf.current = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf.current); }, [value, duration]); return ( {prefix} {display.toLocaleString("en-CA", { minimumFractionDigits: decimals, maximumFractionDigits: decimals, })} {suffix} ); }