Zostel
Forms Quantity Stepper

Quantity Stepper

One fewer, one more: beds, guests, nights. The kit's round controls either side of the count, off at the limits, 44 px to a finger.

Preview

Beds

In the 6 bed mixed dorm, up to 6

2 beds

Nights

At least one, up to 14

3 nights

Usage

tsx
import { QuantityStepper } from "zostel-ui";

const [beds, setBeds] = useState(1);

<QuantityStepper label="Beds" value={beds} onValueChange={setBeds} min={0} max={left} />

{/* in a card's footer */}
<QuantityStepper label="Nights" size="sm" value={nights} onValueChange={setNights} min={1} />

Props

value
Type: number
Default: —

The count.

onValueChange
Type: (value: number) => void
Default: —

Called with the new count, kept between min and max.

label
Type: string
Default: —

What is counted, in the plural (“Beds”): the group’s name, and read after the number (“2 beds”).

singular
Type: string
Default: —

The same for one (“Bed”, “Child”), read after 1 (“1 child”). Without it, a label that ends in s drops the s.

min / max
Type: number
Default: 0 / Infinity

The limits: the minus turns off at min, the plus at max, with aria-disabled, so a button that turns off under the focus keeps it (and does nothing). If they cross, min wins.

step
Type: number
Default: 1

How much one press changes.

size
Type: "default" | "sm"
Default: "default"

36 px controls in a form (the Button’s icon size), 30 px in a card’s footer (icon-sm). Both are 44 px to a finger.

autoFocus
Type: boolean
Default: —

Focus its first button that can act when it mounts: for a stepper that takes the place of the control that had the focus (RoomOption’s Select bed).

disabled
Type: boolean
Default: —

Turns both controls off.

className
Type: string
Default: —

More classes, merged with the component’s own (tailwind-merge).

On zostel.com

A room’s “Select bed” turns into this stepper once a bed is picked (RoomOption does that swap for you, and moves the focus with it). A screen reader hears the group’s name, “Remove one” and “Add one”, and the new count as it changes.