Skip to content

DatePicker

Terminal window
$ npx shadcn@latest add https://lacodda.github.io/dowel/r/date-picker.json
See it liveEmpty, chosen, bounded, and inside a Field.

The trigger is a button, not a typable field. A date input has to answer “what does 03/04/26 mean” in a locale it cannot be sure of, and it answers wrong for half the world. A button showing the date spelled out has no such question. Where typing genuinely matters — a birth date forty years back — a calendar is the wrong control anyway.

<DatePicker
value={releasedOn} // '2026-09-02'
onValueChange={setReleasedOn}
placeholder="Pick a date"
previousMonthLabel="Previous month"
nextMonthLabel="Next month"
/>

What is shown is Intl’s own long form — “2 September 2026” here, “September 2, 2026” in the United States. The stored value never changes.

It closes when a day is chosen. Choosing is the whole errand; waiting for a second dismissing click is one click too many.

name puts the value where a form can find it. A button is not a field, so without it a form submits the screen and loses the date — the component writes a hidden input instead.

<DatePicker name="released_on" ... /> // submits 2026-09-02

The value, the arithmetic and the keyboard are the Calendar’s; this is the field around it.

Prop Type Default
value IsoDate YYYY-MM-DD
onValueChange (value) => void
min, max IsoDate Bounds, inclusive
placeholder string Required — what the trigger says when empty
previousMonthLabel string Required
nextMonthLabel string Required
locale string reader’s own
name string Puts the value in the form
disabled boolean false