Forms & input
Date & time picker
One composable control for due dates, ranges, time, and recurrence — designed for dense, keyboard-driven project planning. Opens from any input as a popover, or embeds inline.
npx shadcn@latest add @orbit/date-pickerModes
Six modes, one component — switch behaviour with a single mode prop. Every demo below is fully interactive and pins today to Jun 24, 2026 for a stable calendar.
Popover
Set display to popover to anchor the panel beneath a 34px trigger field. Outside click and Escape close it; Apply confirms and closes; selection text uses tabular figures so values never shift width.
Trigger states
The input that summons the popover. Error accepts a string that doubles as the help text; clearable adds an inline reset.
A due date is required
Controlled
Pass value + onValueChange to own the state. Single-date modes report a Date (datetime encodes the time in it); range reports { start, end }.
value: Wed Jun 24 2026
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | "single" | "range" | "datetime" | "time" | "presets" | "recurring" | "single" | Behavior and panel layout — calendar, dual-month + shortcuts, time column, repeat rule. |
| display | "inline" | "popover" | "inline" | Embed the panel inline, or anchor it to a trigger field as a popover. |
| value | Date | { start, end } | null | — | Controlled value. Date for single modes; { start: Date | null, end: Date | null } for range. |
| defaultValue | Date | { start, end } | null | — | Initial value when uncontrolled. |
| onValueChange | (value) => void | — | Fires on every selection — day, time, preset, or clear. |
| repeat / defaultRepeat | "none" | "daily" | "weekday" | "weekly" | "monthly" | "yearly" | "custom" | "weekly" | Repeat rule for mode="recurring" — controlled or uncontrolled, with onRepeatChange. |
| openRepeat | boolean | false | Render the recurring mode with its repeat menu already open. |
| today | Date | new Date() | The accent-ringed "today" and the anchor for presets and the default view. Pass a fixed date for stable demos. |
| placeholder | string | per mode | Trigger text when empty — defaults to "Set due date", "Set date range", etc. |
| size | "sm" | "md" | "md" | Trigger height: sm 30px · md 34px. |
| error | boolean | string | — | Danger trigger styling; a string also renders as help text below the field. |
| disabled | boolean | false | Disables the trigger. |
| clearable | boolean | false | Shows an inline × on the trigger that resets the value. |
| open / defaultOpen / onOpenChange | boolean / boolean / (open) => void | — | Popover open state — controlled or uncontrolled (display="popover"). |
| …rest | HTMLAttributes<HTMLDivElement> | — | Everything else is forwarded to the root element, including ref. |
Usage
Open to the most likely date
Default to today or the next business day so the common case is a single click.
Open to an empty, far-off month
Forcing users to navigate back to “now” adds friction to every entry.
Offer presets for common ranges
“Last 7 days” and “This month” save repetitive month-by-month clicking.
Split date and time apart
Keep them in one popover — two disconnected fields invite mismatched values.
Keyboard & accessibility
The day grid uses role=grid with a roving tab stop; arrow keys move across days and months shift automatically to keep the focused day visible. The popover returns focus to the trigger on close, and every control shows the 3px themed focus ring.