DatePicker Composition
Typing and picking, both. Typing is what fast people do and what a date of birth needs; the calendar answers the "second Tuesday" questions a text field cannot.
Usage
Type 18/08/2026, or pick it.
Selected: 2026-08-18
<Field label="Invoice date"> <DatePicker value={date} onValueChange={setDate} min={start} max={end} /></Field>What the parsing does
- ISO first, then day-first with
/,-, or.. Day-first because that is what most of the world writes, and an ambiguous03/04has to pick a side and say so. - A two-digit year expands into this century.
- 31 February is rejected, rather than rolling quietly into March — the classic
new Date()trap. - Unparseable text clears the value on blur instead of silently keeping the old date, which is the version that ships wrong data.
- The grid is always six weeks, so the popover does not change height between months.
Do
Pass min and max when the range is known — out-of-range days are disabled rather than merely rejected afterwards.
Don't
Use it for a month or a year on its own; a Select with twelve options is faster and unambiguous.
Opening
Clicking the field opens the calendar, and so does the calendar button. Typing still works either way, and the popover anchors to the whole field rather than to the button, so it lines up with the control however it was opened. Times of day are the TimePicker's job.
Props
| Prop | Type | Default | Notes |
|---|---|---|---|
| value / defaultValue | Date | null | — | Local calendar dates. Time is ignored. |
| onValueChange | (value: Date | null) => void | — | Fires on blur and on picking a day. |
| min / max | Date | — | Inclusive bounds. Days outside are disabled. |
| format | (date: Date) => string | — | How the chosen date reads in the field. Defaults to the viewer’s locale. |
| weekStartsOn | 0 | 1 | 1 | Monday by default; 0 for Sunday. |