Guest Picker
Who's coming: a field with the total that opens a stepper for each kind of guest, a popover on a desk and a sheet on a phone.
Preview
Zostel Homes Bhor: who's coming
Beside the dates: the split look
Usage
import { GuestPicker } from "zostel-ui";
const [guests, setGuests] = useState({ adults: 2, children: 0 });
<GuestPicker
aria-label="Guests"
groups={[
{ id: "adults", label: "Adults", singular: "Adult", hint: "18 and over", min: 1 },
{ id: "children", label: "Children", singular: "Child", hint: "Under 18" },
]}
value={guests}
onValueChange={setGuests}
maxTotal={room.sleeps}
/>
{/* beside the split date picker */}
<GuestPicker variant="split" … />Props
| Prop | Type | Default | Description |
|---|---|---|---|
groups | { id; label; singular?; hint?; min?; max? }[] | — | The kinds of guest, each with its own stepper and limits. label is the plural the panel shows (“Children”); singular is the same for one (“Child”), so a count reads “1 child”. Without it, a label that ends in s drops the s. |
value · onValueChange | Record<string, number> | — | How many of each, by id. |
maxTotal | number | Infinity | The most guests in all: the steppers stop there. A value over it (the room changed to a smaller one), or outside a group’s limits, is brought inside (trimmed from the last group back, never below a group’s min) and handed back through onValueChange. |
variant | "field" | "split" | "field" | One line (“3 guests”), or a label over the count to sit beside the split date picker. |
aria-labelledby · aria-label | string | — | The field’s name, required: the label, then what the field shows (“Who’s coming, 3 guests”), so the visible words are in it. It describes the mix too (“2 adults, 1 child”). In development, a field with no label warns in the console. |
className | string | — | More classes on the field. |
groups{ id; label; singular?; hint?; min?; max? }[]The kinds of guest, each with its own stepper and limits. label is the plural the panel shows (“Children”); singular is the same for one (“Child”), so a count reads “1 child”. Without it, a label that ends in s drops the s.
value · onValueChangeRecord<string, number>How many of each, by id.
maxTotalnumberInfinityThe most guests in all: the steppers stop there. A value over it (the room changed to a smaller one), or outside a group’s limits, is brought inside (trimmed from the last group back, never below a group’s min) and handed back through onValueChange.
variant"field" | "split""field"One line (“3 guests”), or a label over the count to sit beside the split date picker.
aria-labelledby · aria-labelstringThe field’s name, required: the label, then what the field shows (“Who’s coming, 3 guests”), so the visible words are in it. It describes the mix too (“2 adults, 1 child”). In development, a field with no label warns in the console.
classNamestringMore classes on the field.
On zostel.com
Xostel stays (the partner hostels on zostel.com) ask for Adults (18 and over) and Children (under 18) beside the dates in the Select Room header. Zostel’s own stays count beds per room instead (RoomOption’s stepper).