Components · Learning
StreakCounter
A running count that rolls when it changes. Only a gain is celebrated.
Use it
<StreakCounter count={6} label="day streak" />How it moves
| When | Role | What moves |
|---|---|---|
| The count goes up | exit, enter, celebration | The old number fades up and out, the new one rises in, and the pill pops from the celebration scale back to 1 |
| The count goes down or resets | exit, enter | The numbers swap the same way. The pill does not pop |
| First shown | none | Nothing moves |
Rules:
- Only a gain is celebrated. A lost streak is never animated for attention; the number changes quietly.
- The pop belongs to the pill, not the number, so the number stays readable while it changes.
- The counter never loops or pulses between changes.
Reduced motion: the celebration scale is 1 and the enter and exit distances are 0, so nothing moves. The old number fades out and the new one fades in.
Screen readers: the counter is a status region, so a new count is read out without moving focus. The leaving number is hidden from them.
CSS variables used: --ss-motion-celebration-scale, --ss-motion-celebration-spring, --ss-motion-celebration-spring-duration, --ss-motion-enter-distance, --ss-motion-enter-spring, --ss-motion-enter-spring-duration, --ss-motion-exit-distance, --ss-motion-exit-duration, --ss-motion-exit-easing.
The flame is the Icon component. It catches only when the count goes up (Icon motion: flicker), at the same moment as the pop. It never flickers on its own. Pass flame={false} to hide it.