Badge with motion: a new count rolls up or down while the badge glides to its width, a new color pulses the dot, and it pops in when added.
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-badge.jsonInstallation
$ pnpm dlx shadcn@latest add https://dashral.com/r/motion-badge.jsonAdds components/dashral/motion/badge.tsx, the Badge it builds on (in components/dashral/), motion and the motion files every motion component shares. With the registry in your components.json:
$ pnpm dlx shadcn@latest add @dashral/motion-badgeUsage
The same as Badge, imported from components/dashral/motion/: swap the import and it moves.
import { AnimatePresence } from "motion/react"
import { Badge } from "@/components/dashral/motion/badge"
<AnimatePresence>{unread > 0 && <Badge>{unread}</Badge>}</AnimatePresence>Examples
Counts on wheels
A number turns on odometer wheels, each digit as far as it travelled; +25 spins them further, and max={99} reads 99+ past it.
Unread counts
New message pops a badge onto a conversation or rolls its count up; open one and its badge shrinks away while the total rolls down.
Compared with Default
A new label or count replaces the old one at once; a new color changes in place.
Motion
A new label crosses over, a count rolling up as it rises and down as it falls, while the badge glides to its width; a new color pulses the dot; it pops in and shrinks out inside AnimatePresence.
How the two editions differ in general, and which to use where: Motion.
API reference
Every prop of Badge, and every attribute of the element it renders. What the Motion edition adds is marked Motion.
Badge
Also takes every prop of <span>(opens in a new tab).
| Prop | Type | Default |
|---|---|---|
max | number
| — |
variant | "solid" | "soft" | "outline"How much it stands out. | "solid" |
color | "primary" | "neutral" | "info" | "success" | "warning" | "destructive" | "highlight"What it means. | "primary" (outline: "neutral") |
dot | booleanA status dot before the label. | false |
className | stringExtra classes, merged with cn() so yours win. | — |
No asChild: for a link that looks like a badge, use the default Badge.
Motion
- A number for its label turns on odometer wheels: each digit as far as it travelled, softly blurred as it turns, the badge gliding to its width as digits come and go; past max it reads 99+.
- When its text changes, the new text rises in as the old leaves upward; a number that falls rolls the other way. The badge glides to the new width (no overshoot).
- A new color pulses the dot once (--duration-considered).
- Added inside AnimatePresence, it pops in from 60% with a small overshoot, and shrinks out quickly when taken away; on the page's first paint it's simply there.
- With reduced motion everything only fades, and the width follows at once.