Count Up
unlumen-ui/count-upFreeComponent
An animated number counter that springs to its target value when it enters the viewport, with support for decimals, separators, and direction.
Install it
npx shadcn@latest add https://ui.unlumen.com/r/count-up.jsonSource
1"use client";23import * as React from "react";4import {5 AnimatePresence,6 motion,7 useInView,8 useMotionValue,9 useSpring,10 useTransform,11 type MotionValue,12} from "motion/react";13import useMeasure from "react-use-measure";1415import { cn } from "@/lib/utils";1617type DigitEffect = "none" | "fade" | "blur" | "slide";1819interface CountUpProps {20 to: number;21 from?: number;22 direction?: "up" | "down";23 delay?: number;24 duration?: number;25 digitEffect?: DigitEffect;26 className?: string;27 startWhen?: boolean;28 separator?: string;29 onStart?: () => void;30 onEnd?: () => void;31}3233type OdometerDigitProps = {34 springValue: MotionValue<number>;35 /** place value: 1, 10, 100, 1000 … */36 place: number;37};3839function OdometerDigit({ springValue, place }: OdometerDigitProps) {40 const [ref, { height }] = useMeasure();4142 const y = useTransform(springValue, (v) => {43 if (!height) return 0;44 const digit = (Math.abs(v) / place) % 10;45 return -digit * height;46 });4748 return (49 <span50 style={{51 position: "relative",52 display: "inline-block",53 width: "1ch",54 overflowY: "clip",55 overflowX: "visible",56 lineHeight: 1,57 fontVariantNumeric: "tabular-nums",58 }}59 >60 <span ref={ref} style={{ visibility: "hidden", display: "block" }}>61 062 </span>63 <motion.span64 style={{65 y,66 position: "absolute",67 top: 0,68 left: 0,69 right: 0,70 display: "flex",71 flexDirection: "column",72 }}73 >74 {/* 11 digits (0–9 + repeated 0) so the 9→0 wrap is seamless */}75 {Array.from({ length: 11 }, (_, i) => (76 <span77 key={i}78 style={{79 display: "flex",80 alignItems: "center",81 justifyContent: "center",82 height: height || "1em",83 }}84 >85 {i % 10}86 </span>87 ))}88 </motion.span>89 </span>90 );91}9293type CharSlotProps = {94 char: string;95 charKey: string;96 effect: Exclude<DigitEffect, "none" | "slide">;97 countingUp: boolean;98};99100const CHAR_VARIANTS = {101 fade: {102 initial: { opacity: 0, scale: 0.7 },103 animate: { opacity: 1, scale: 1 },104 exit: { opacity: 0, scale: 0.7 },105 transition: { duration: 0.14, ease: "easeOut" },106 overflow: "hidden" as const,107 },108 blur: {109 initial: (up: boolean) => ({110 opacity: 0,111 filter: "blur(8px)",112 y: up ? -8 : 8,113// … truncated
What it pulls in
npm packages
Files it writes
More from Unlumen Ui
All 233 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| AI Chatai-chat | Unlumen Ui | Components | Paid | 2 deps | |
| Vercel Animate Countanimate-count | Unlumen Ui | Components | Free | 1 dep | |
| Animate Digitsanimate-digits | Unlumen Ui | Components | Free | 1 dep | |
| Animated Inputanimate-text-input-typing | Unlumen Ui | Components | Paid | 1 dep | |
| Animated Listanimated-list | Unlumen Ui | Components | Free | 1 dep | |
| Apple Switchapple-switch | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Barsaurora-bars | Unlumen Ui | Components | Free | 1 dep | |
| Aurora Bluraurora-blur | Unlumen Ui | Components | Free | 2 deps |
