Four hand-built date pickers for real jobs — a stay range with nights and price, a deadline with quick picks, a recurring schedule and an appointment slot finder — with months that slide and selections that spring.
Booking range
booking-range.tsxCheck-in and check-out on one calendar with a hover preview, booked nights blocked, a minimum stay and a total that rolls as the range changes.
| Prop | Type | Default | Description |
|---|---|---|---|
today | Date | Oct 2, 2026 | Days before this are disabled. Pass new Date() in your app. |
pricePerNight / cleaningFee | number | 184 / 45 | Used for the running total. |
currency | string | "USD" | ISO currency for formatting. |
minNights | number | 2 | Shortest allowed stay; shorter picks shake with a message. |
booked | string[] | — | Unavailable nights as YYYY-MM-DD. |
defaultCheckIn / defaultCheckOut | Date | null | — | Initial range. |
onChange / onReserve | (range: BookingRange) => void | — | Fires with { checkIn, checkOut, nights, total }. |
className | string | — | Extra classes on the root element. |
Deadline
deadline.tsxQuick picks such as tomorrow, end of week and next week beside a calendar, with a sliding preset pill and a relative due label.
| Prop | Type | Default | Description |
|---|---|---|---|
today | Date | Oct 2, 2026 | Anchor for presets and the relative label. |
defaultValue | Date | null | — | Initially selected deadline. |
presets | { label: string; days: number }[] | — | Quick picks as days from today. |
onChange | (date: Date | null) => void | — | Fires on every pick or clear. |
onConfirm | (date: Date | null) => void | — | Set deadline button. |
className | string | — | Extra classes on the root element. |
Recurring schedule
recurring.tsxWeekday toggles, an every-N-weeks stepper and time chips, previewed live as dots on a calendar with the next three dates spelled out.
| Prop | Type | Default | Description |
|---|---|---|---|
today | Date | Oct 2, 2026 | Earliest selectable start date. |
defaultDays | number[] | [0, 2] | Weekdays, 0 = Monday. |
times / defaultTime | string[] / string | — | Time chips and the initial one. |
defaultInterval | number | 1 | Repeat every N weeks (1–4). |
defaultStart | Date | — | First possible occurrence. |
onChange / onSave | (s: RecurringSchedule) => void | — | Fires with { days, time, interval, start }. |
className | string | — | Extra classes on the root element. |
Appointment slots
appointment.tsxA seven-day strip with a sliding selection, a time grid that crossfades per day and a booking bar that springs up with a confirmed state.
| Prop | Type | Default | Description |
|---|---|---|---|
today | Date | Oct 2, 2026 | First day of the strip. |
host / title | string | — | Who the call is with and what it is. |
durationMinutes | number | 30 | Shown in the header and booking bar. |
timezone | string | — | Label under the time grid. |
getSlots | (date: Date) => string[] | — | Open times for a day; empty days are dimmed. |
defaultTime | string | null | null | Preselect a time on the first open day. |
onBook | (slot: { date: Date; time: string }) => void | Promise<void> | — | Resolve to show the booked state. |
className | string | — | Extra classes on the root element. |
Install the whole set
Installs every date pickers variant at once. Each section above has its own command for a single variant.
Pro installs use your private registry token. Add the @geturui-pro registry once — setup guide. The command works after you get Pro.
Accessibility
- Calendars are ARIA grids with one tab stop: arrows move by day and week, Home and End jump to the week's edges, PageUp and PageDown change month (Shift for year).
- Disabled and booked days are real disabled buttons with a spoken reason, and month changes are announced through a live region.
- Month slides, number rolls and pops collapse to fades when reduced motion is requested.