## Rolling Counter (S—043)

A number stepper whose digits roll like an odometer, with springy plus and minus buttons.

- URL: https://sundaeui.dev/components/rolling-counter
- Category: Forms & inputs · Art direction: Playful
- Access: Free (no account needed)
- Stack: React 18+, TypeScript, plain CSS; dependencies: none
- Install: `npx shadcn@latest add https://sundaeui.dev/r/rolling-counter.json`
- Tags: stepper, form, counter, animated, number, input

Each digit is its own column that rolls only as far as it needs to, so 99 → 100 rolls the tens and hundreds while the ones flip over.
Under it is a real spinbutton: arrow keys step, Page keys jump by ten and Home/End go to the limits.

### Usage

```tsx
import { RollingCounter } from '@/components/sundae/rolling-counter'

const [seats, setSeats] = useState(2)

<RollingCounter value={seats} onValueChange={setSeats} min={1} max={20} label="Seats" />
```

### Props

- `value` (`number`): Controlled value.
- `defaultValue` (`number`, default `0`): Initial value when uncontrolled.
- `onValueChange` (`(v: number) => void`): Called with the clamped value.
- `min / max / step` (`number`, default `0 / 999 / 1`): Range and step.
- `label` (`string`, default `'Quantity'`): Accessible name.
- `size` (`number`, default `56`): Font size of the number, px.
- `variant` (`'pill' | 'plain'`, default `'pill'`): Pill container or bare.
- `fill` (`'dark' | 'light'`, default `'dark'`): Surface: dark or light.

### When to use

- Quantities, seats, guests and other small integers.
- Live counters (followers, votes) where a rolling change feels rewarding.

### When not to use

- Free-form or decimal numbers: use a text input with inputMode="decimal".
- Ranges over a few hundred where typing is faster.

### Accessibility

- The number is role="spinbutton" with aria-valuenow/min/max.
- Buttons have explicit labels ("Increase Seats") and disable at the limits.
- Reduced motion turns the roll into an instant change.

### Keyboard

- ↑ / →: Increase by step
- ↓ / ←: Decrease by step
- Page Up / Down: Change by ten steps
- Home / End: Jump to min / max
