Build / Molecules
DayStrip
Horizontal day picker for a booking flow's availability step.
Each day carries how many slots are free, so the choice is informed before it is made — a day with two openings looks different from one with twelve, and a full day is disabled rather than a dead end. Month changes are labelled inline so a strip spanning a boundary stays legible.
Renders as a radio group: arrow keys move along the strip, and the selection is announced with its date and availability.
import { DayStrip } from '@meetcard/deck'Example
<DayStrip value={day} onChange={setDay} today="2026-09-01" timeZone="America/Denver" days={[ { date: '2026-09-01', slotCount: 6 }, { date: '2026-09-02', slotCount: 0 }, ]} />Stories
Source
const Default = args => {
const [value, setValue] = useState(args.value)
return (
<DayStrip
today="2026-09-01"
timeZone="America/Denver"
days={[
{ date: '2026-09-01', slotCount: 2 },
{ date: '2026-09-02', slotCount: 6 },
{ date: '2026-09-03', slotCount: 9 },
{ date: '2026-09-04', slotCount: 4 },
{ date: '2026-09-05', slotCount: 0 },
{ date: '2026-09-08', slotCount: 7 },
{ date: '2026-09-09', slotCount: 1 },
]}
value={value}
onChange={setValue} />
);
};A day chosen. The selection is announced with its date and how many slots it has.
Source
const Selected = args => {
const [value, setValue] = useState(args.value)
return (
<DayStrip
today="2026-09-01"
timeZone="America/Denver"
days={[
{ date: '2026-09-01', slotCount: 2 },
{ date: '2026-09-02', slotCount: 6 },
{ date: '2026-09-03', slotCount: 9 },
{ date: '2026-09-04', slotCount: 4 },
{ date: '2026-09-05', slotCount: 0 },
{ date: '2026-09-08', slotCount: 7 },
{ date: '2026-09-09', slotCount: 1 },
]}
value={value}
onChange={setValue} />
);
};Days with no openings are disabled rather than left as a dead end.
Source
const FullyBooked = args => {
const [value, setValue] = useState(args.value)
return (
<DayStrip
today="2026-09-01"
timeZone="America/Denver"
days={[
{ date: '2026-09-01', slotCount: 0 },
{ date: '2026-09-02', slotCount: 0 },
{ date: '2026-09-03', slotCount: 3 },
]}
value={value}
onChange={setValue} />
);
};The month is re-labelled wherever the strip crosses a boundary.
Source
const AcrossMonths = args => {
const [value, setValue] = useState(args.value)
return (
<DayStrip
today="2026-08-30"
timeZone="America/Denver"
days={[
{ date: '2026-08-30', slotCount: 3 },
{ date: '2026-08-31', slotCount: 5 },
{ date: '2026-09-01', slotCount: 2 },
{ date: '2026-09-02', slotCount: 8 },
]}
value={value}
onChange={setValue} />
);
};Props
| Prop | Type | Default | Description |
|---|---|---|---|
daysrequired | DayOption[] | — | — |
className | string | — | — |
label | string | 'Pick a day' | — |
locale | string | — | — |
onChange | (date: string) => void | — | — |
timeZone | string | — | IANA zone the days are expressed in, shown alongside the label. |
today | string | — | ISO date rendered with a "Today" marker. |
value | string | — | ISO date of the selected day. |