DateRangePicker
A button trigger that opens a popover with one or two adjacent calendars in range mode. The anchor of every booking flow — start → end.
Two-month (desktop default)#
Loading…
Single month (mobile)#
Loading…
Props#
| Prop | Type | Default | Description |
|---|---|---|---|
| value | DateRange | undefined | — | |
| defaultValue | DateRange | undefined | — | |
| onValueChange | ((range: DateRange) => void) | undefined | — | |
| months | enum | 2 | Number of months shown side-by-side. Default `2` for desktop, `1` for mobile. |
| placeholder | string | undefined | Pickup → Return | Placeholder shown when no range is set. |
| format | ((d: Date) => string) | undefined | (d: Date) => d.toLocaleDateString() | Custom formatter. Default uses each date's `toLocaleDateString()`. |
| width | string | number | undefined | 320 | Pixel width of the trigger. |
| disabled | boolean | undefined | — | |
| isDateDisabled | ((date: Date) => boolean) | undefined | — | Optional disable predicate forwarded to each Calendar. |
| aria-label | string | undefined | — | |
| id | string | undefined | — |
Selection model#
- First click sets
from. - Second click sets
to. If the user clicks an earlier date thanfrom, the two are swapped so the range always reads forward. - A third click starts a new range with the third date as
from. - While
fromis set buttois not, hover-preview shades the in-progress range using theaccent-dimtoken so the user sees the span before committing.
Composition#
The underlying Calendar accepts mode="range" directly — wrap with a
Popover yourself if you need a custom trigger.