UNPKG

lightswind

Version:

A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.

114 lines 5.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CountUp = CountUp; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const framer_motion_1 = require("framer-motion"); const utils_1 = require("@/components/lib/utils"); // Helper function to format the number const formatValue = (val, precision, sep) => { return val .toFixed(precision) .replace(/\B(?=(\d{3})+(?!\d))/g, sep); }; const easingFunctions = { linear: [0, 0, 1, 1], easeIn: [0.42, 0, 1, 1], easeOut: [0, 0, 0.58, 1], easeInOut: [0.42, 0, 0.58, 1], }; const animationStyles = { default: { type: "tween" }, bounce: { type: "spring", bounce: 0.25 }, spring: { type: "spring", stiffness: 100, damping: 10 }, gentle: { type: "spring", stiffness: 60, damping: 15 }, energetic: { type: "spring", stiffness: 300, damping: 20 }, }; const colorSchemes = { default: "text-foreground", gradient: "bg-clip-text text-transparent bg-gradient-to-r from-primarylw to-purple-600", primary: "text-primary", secondary: "text-secondary", custom: "", // use customColor }; function CountUp({ value, duration = 2, decimals = 0, prefix = "", suffix = "", easing = "easeOut", separator = ",", interactive = false, triggerOnView = true, className, numberClassName, animationStyle = "default", colorScheme = "default", customColor, onAnimationComplete, }) { const [hasAnimated, setHasAnimated] = (0, react_1.useState)(false); const containerRef = (0, react_1.useRef)(null); const count = (0, framer_motion_1.useMotionValue)(0); const rounded = (0, framer_motion_1.useTransform)(count, function (latest) { return formatValue(latest, decimals, separator); }); const animationConfig = { ...animationStyles[animationStyle], ease: easingFunctions[easing], duration: animationStyle === "default" ? duration : undefined, }; (0, react_1.useEffect)(() => { if (!triggerOnView) { (0, framer_motion_1.animate)(count.get(), value, { ...animationConfig, onUpdate: function (latest) { return count.set(latest); }, onComplete: function () { setHasAnimated(true); if (onAnimationComplete) onAnimationComplete(); }, }); return; } const observer = new IntersectionObserver(function ([entry]) { if (entry.isIntersecting && !hasAnimated) { (0, framer_motion_1.animate)(count.get(), value, { ...animationConfig, onUpdate: function (latest) { return count.set(latest); }, onComplete: function () { setHasAnimated(true); if (onAnimationComplete) onAnimationComplete(); }, }); } }, { threshold: 0.1 }); if (containerRef.current) observer.observe(containerRef.current); return function () { return observer.disconnect(); }; }, [value, triggerOnView, hasAnimated]); (0, react_1.useEffect)(function () { if (hasAnimated || !triggerOnView) { (0, framer_motion_1.animate)(count.get(), value, { ...animationConfig, onUpdate: function (latest) { return count.set(latest); }, onComplete: onAnimationComplete, }); } }, [value, animationConfig, hasAnimated, triggerOnView, onAnimationComplete]); const colorClass = colorScheme === "custom" && customColor ? "" : colorSchemes[colorScheme]; const getHoverAnimation = function () { if (!interactive) return {}; return { whileHover: { scale: 1.05, filter: "brightness(1.1)", transition: { duration: 0.2 }, }, whileTap: { scale: 0.95, filter: "brightness(0.95)", transition: { duration: 0.1 }, }, }; }; return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, // Using cn directly with string literals for classes className: (0, utils_1.cn)("inline-flex items-center justify-center text-4xl font-bold text-black dark:textwhite", className), children: (0, jsx_runtime_1.jsxs)(framer_motion_1.motion.div, { ...getHoverAnimation(), className: (0, utils_1.cn)("flex items-center transition-all", colorClass, numberClassName), style: colorScheme === "custom" && customColor ? { color: customColor } : undefined, children: [prefix && (0, jsx_runtime_1.jsx)("span", { className: "mr-1 text-foreground", children: prefix }), (0, jsx_runtime_1.jsx)(framer_motion_1.motion.span, { className: " text-foreground", children: rounded }), suffix && (0, jsx_runtime_1.jsx)("span", { className: "ml-1 text-foreground", children: suffix })] }) })); } //# sourceMappingURL=count-up.js.map