ComponentsNumbers
Stat reveal
A stat counts up when it scrolls in.
Installation
$ npx shadcn@latest add @textlab/stat-revealNeeds @textlab in your components.json. Setup takes a minute.
Usage
usage.tsx
import { StatReveal } from "@/components/textlab/stat-reveal/stat-reveal";
<StatReveal value={12400} suffix="+" />Variants
countspringscrambleProps
| Prop | Type | Default | Description |
|---|---|---|---|
| value* | number | – | The final number. |
| variant | "count" | "spring" | "scramble" | "count" | Ease up, overshoot and settle, or shuffle digits then lock in. |
| from | number | 0 | Where the count starts. |
| prefix | string | – | Text before the number. |
| suffix | string | – | Text after the number. |
| format | Intl.NumberFormatOptions | – | Number formatting. |
| locale | string | "en-US" | Formatting locale. |
| trigger | "mount" | "inView" | "manual" | "inView" | What starts the animation. manual follows `active`. |
| once | boolean | true | In view: play once instead of on every entry. |
| delay | number | 0 | Seconds before the first part moves. |
| duration | number | 1.8 | Seconds each part takes. |
| ease | EaseName | [number, number, number, number] | "emphasized" | Easing token or cubic bezier. |
| as | ElementType | "span" | Rendered element. |
| reducedMotion | "user" | "always" | "never" | "user" | user follows the OS setting; always shows the still version. |
| className | string | – | Merged onto the root. |
| onComplete | () => void | – | Called when a one-shot animation finishes. |
When to use it
Reach for it
- Stats bands and impact numbers on marketing pages.
- Any number shown once that deserves a moment of arrival.
Skip it
- Numbers that keep changing; use rolling-number.
- Several dozen stats on one screen.
Accessibility and motion
Accessibility
- Screen readers read the final value, never the in-between numbers.
- The final width is reserved, so nothing shifts while counting.
Motion
- Counts with the emphasized ease: fast early, slow landing.
- Starts when 45% of the stat is visible.
Reduced motion. Shows the final value immediately.
Performance
- One motion value; text updates outside React renders for count and spring.