# Date pickers

> 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.

- Collection: Examples
- Tier: pro
- Docs: https://geturui.com/docs/date-pickers
- Install: `npx shadcn@latest add @geturui-pro/date-pickers`
- Dependencies: motion, lucide-react

## Variants

### Booking range

Check-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.

Install: `npx shadcn@latest add @geturui-pro/date-pickers-booking-range`

```tsx
import { BookingRangePicker } from "@/components/examples/date-pickers/booking-range";

export function Stay() {
  return <BookingRangePicker pricePerNight={184} cleaningFee={45} minNights={2} onReserve={(range) => reserve(range)} />;
}
```

| 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

Quick picks such as tomorrow, end of week and next week beside a calendar, with a sliding preset pill and a relative due label.

Install: `npx shadcn@latest add @geturui-pro/date-pickers-deadline`

```tsx
import { DeadlinePicker } from "@/components/examples/date-pickers/deadline";

export function TaskDue() {
  return <DeadlinePicker today={new Date()} onConfirm={(date) => setDue(date)} />;
}
```

| 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

Weekday toggles, an every-N-weeks stepper and time chips, previewed live as dots on a calendar with the next three dates spelled out.

Install: `npx shadcn@latest add @geturui-pro/date-pickers-recurring`

```tsx
import { RecurringPicker } from "@/components/examples/date-pickers/recurring";

export function StandupSchedule() {
  return <RecurringPicker defaultDays={[0, 2, 4]} defaultTime="9:30 AM" onSave={(s) => saveSchedule(s)} />;
}
```

| 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

A 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.

Install: `npx shadcn@latest add @geturui-pro/date-pickers-appointment`

```tsx
import { AppointmentPicker } from "@/components/examples/date-pickers/appointment";

export function BookCall() {
  return <AppointmentPicker host="Ana Ruiz" getSlots={(d) => openTimes(d)} onBook={(slot) => api.book(slot)} />;
}
```

| 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. |

## 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.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
