Snai3i-LandingPage-FormBuilder / frontend / src / pages / Home / components / StatComponent / index.tsx
index.tsx
Raw
import {
  animate,
  motion,
  useInView,
  useMotionValue,
  useTransform,
} from 'framer-motion';
import React, { useEffect, useRef } from 'react';

interface KeyValueDisplayProps {
  keyName: string;
  value: number;
}

const KeyValueDisplay: React.FC<KeyValueDisplayProps> = ({
  keyName,
  value,
}) => {
  const ref = useRef<HTMLParagraphElement>(null);
  const isInView = useInView(ref);
  const count = useMotionValue(0);
  const rounded = useTransform(count, (latest) => Math.round(latest));

  useEffect(() => {
    if (!isInView) return;
    const controls = animate(count, value, { duration: value>1000? 3 : 2 });
    return controls.stop;
  }, [isInView]);

  return (
    <span className="flex flex-col items-center justify-center gap-2">
      <motion.p
        ref={ref}
        className={`text-primary text-7xl lg:text-8xl md:text-7xl text-center font-bold ${
          value > 999 ? 'min-w-[14rem]' : 'min-w-[7rem]'
        } `}
      >
        {rounded}
      </motion.p>
      <motion.p
        variants={{
          visible: { opacity: 1, y: 0 },
          hidden: { opacity: 0, y: 10 },
        }}
        initial="hidden"
        whileInView="visible"
        viewport={{ once: true }}
        transition={{ duration: 0.7, ease: 'easeInOut' }}
        className=" text-secondary text-2xl max-w-md font-extrabold mb-8"
      >
        {keyName}
      </motion.p>
    </span>
  );
};

export default KeyValueDisplay;