Components · Date & time

Date-time picker

One controlled control that yields a date, a time, or a datetime by granularity. A styled native DatePicker sits beside a native TimeInput inside a Surface group — each half keeps its own accessible picker. The popover below visualizes that open state in DS tokens: a month grid and a time list, one instant selected.

granularity datetime · timezoneLabel "PT" · picker open on the date half
07/11/2026
09:30 AM
PT

Adoption Day — Riverside Park. The real DatePicker / TimeInput defer to each browser's native accessible calendar/time picker; this popover shows that open state in DS tokens. Selected Sat Jul 11 · 9:30 AM → value 2026-07-11T09:30 · Jul 2 carries the today ring, timezoneLabel is a decorative PT suffix.

framed inset · invalid ring · date-only & time-only granularity
framed · Surface inset well
08/14/2026
07:00 AM

Vaccine-clinic call time — framed wraps the pair in a bordered surface-2 well.

invalid · both halves → error ring
02/30/2026
--:-- --

Enter a valid departure — that date doesn't exist.

granularity date · single half
07/20/2026

Foster start — value is a bare 2026-07-20, no time half.

granularity time · step 15 · tz suffix
06:15 PM
PT

Kennel check-in — value is 18:15; stepMinutes={15} drives the native step.

granularity = date | datetime (default) | time picks which halves render and the value shape. invalid flips both halves to the error ring; framed draws the inset well; min/max bound the active half.

value / onChange
Controlled string in the granularity's shape — "YYYY-MM-DD", "HH:MM", or "YYYY-MM-DDTHH:MM". Partial values (date, no time) are preserved verbatim. splitDateTime / joinDateTime expose the halves.
granularity
'date' | 'datetime' (default) | 'time' — chooses the rendered halves and the value shape.
stepMinutes / timezoneLabel
stepMinutes sets the native time step (minutes → seconds). timezoneLabel renders a small, purely-decorative suffix (e.g. PT).
invalid / framed / min·max
invalid flips both halves to the error ring; framed wraps the group in a bordered surface-2 inset well; min/max bound the active half; also disabled, required.

Source · ds/datetime/DateTimePicker.tsx@phauna/ds DatePicker (styled native date) + ds/events/TimeInput (styled native time), grouped in a Surface; splitDateTime / joinDateTime for the halves.