Skip to main content

DatePicker

MD3 date picker: a calendar with a year picker and a text-input mode, shown inline or as a modal dialog. For the docked variant (a text field with a calendar dropdown) use DatePickerField.

Inline calendar​

Pickers report values value-first: onChange(value) receives a Date (or a [start, end] pair in range mode). Use value for a controlled picker or defaultValue for an uncontrolled one.

Select date
Wed, Jun 10
June 2026
SundayMondayTuesdayWednesdayThursdayFridaySaturday

Selected: Wed Jun 10 2026

const [date, setDate] = useState<Date | null>(null)

<DatePicker value={date} onChange={(d) => setDate(d as Date)} />

Click the month label to switch to the year picker. min / max limit the selectable dates, and locale sets month / weekday names, the first day of the week, and the input format (default 'en-US').

Pass open to show the picker as a modal dialog (scrim, focus trap, Escape) — the equivalent of Compose's DatePickerDialog. It adds the Cancel / OK row with draft / commit semantics: onChange reports each pick (the draft), OK or Enter calls onAccept, and Cancel, Escape, or a scrim click reverts the value and calls onCancel. onClose(reason) asks you to close, with 'accept' | 'cancel' | 'escapeKeyDown' | 'backdropClick'.

Saved: —
const [open, setOpen] = useState(false)
const [draft, setDraft] = useState<Date | null>(null)

<Button onClick={() => setOpen(true)}>Pick a date</Button>
<DatePicker
open={open}
onClose={(reason) => setOpen(false)}
value={draft}
onChange={(d) => setDraft(d as Date)}
onAccept={(d) => save(d as Date)}
/>

Passing onAccept or onCancel without open renders the same action row on an inline picker.

Range​

range selects a start and end date; the value is a [start, end] tuple (DateRange, either end may be null while picking).

Select dates
Fri, Jun 5 – Fri, Jun 12
June 2026
SundayMondayTuesdayWednesdayThursdayFridaySaturday

Fri Jun 05 2026 → Fri Jun 12 2026

const [range, setRange] = useState<DateRange>([null, null])

<DatePicker range value={range} onChange={(v) => setRange(v as DateRange)} />

Input mode​

The header's edit icon switches between the calendar and text input. Start in input mode with defaultMode="input", control it with mode + onModeChange, or hide the toggle with showModeToggle={false}. Typed text is parsed in the locale's field order and invalid text shows an error.

Select date
Wed, Jun 10
<DatePicker defaultMode="input" defaultValue={new Date(2026, 5, 10)} />

Docked: DatePickerField​

DatePickerField is an outlined text field with a trailing calendar button that opens the calendar in a dropdown. Typed dates commit on Enter or blur; picking a day commits immediately (no action row). onChange(date) receives the date, or null when the field is cleared. The helper text defaults to the locale's format (e.g. MM/DD/YYYY).

MM/DD/YYYY
const [date, setDate] = useState<Date | null>(null)

<DatePickerField label="Event date" value={date} onChange={setDate} />

Localization​

locale localizes dates, and every built-in string is a *Label prop with an English default (titleLabel, okLabel, cancelLabel, previousMonthLabel, switchToInputLabel, getErrorLabel, …).

日付を選択
6月10日(水)
2026年6月
日曜日月曜日火曜日水曜日木曜日金曜日土曜日
<DatePicker locale="ja-JP" titleLabel="日付を選択" okLabel="OK" cancelLabel="キャンセル" />

Accessibility​

  • The day grid is an APG grid with a single Tab stop: arrow keys move by day / week, PageUp / PageDown by month, Shift+PageUp / PageDown by year, Home / End to the first / last day of the month, and Enter / Space select. Today and range positions are announced via todayLabel, startDateLabel, endDateLabel, and inRangeLabel.
  • The month label is a menu button that opens the year picker.
  • The modal picker traps focus, closes on Escape, and returns focus to the opener.
  • DatePickerField's popup is a non-modal role="dialog" (named by dialogLabel): opening moves focus to the selected day (else today); Escape or a pick closes it and returns focus to the toggle.

Props​

DatePicker​

PropTypeDefaultDescription
cancelLabelstringCancelDismiss button label.
defaultModeenumcalendarUncontrolled initial display mode.
defaultValueDate | DateRange | null—Uncontrolled initial value.
endDateLabelstringEnd dateRange end: cell prefix, headline placeholder and input label.
getErrorLabel((error: DateInputError, pattern: string) => string)—Input-mode error message. Defaults to Compose's English strings.
inputLabelstringDateLabel of the single-date text field in input mode.
inRangeLabelstringIn rangePrefix announced on days inside the range.
localestringen-USBCP-47 locale for month / weekday names, the week's first day and the input format.
maxDate—Latest selectable date (inclusive).
minDate—Earliest selectable date (inclusive).
modeenum—Controlled display mode (calendar grid or text input).
nextMonthLabelstringNext monthAccessible label of the next-month button.
noSelectionLabelstring'Selected date' ('Entered date' in input mode)Headline shown while no date is selected (single mode).
okLabelstringOKConfirm button label.
onAccept((value: Date | DateRange) => void)—OK / Enter commits the draft. Passing `onAccept`, `onCancel` or `open` renders the Cancel / OK action row (m3 anatomy; Compose `DatePickerDialog`). OK is enabled once a date (or a full range) is set.
onCancel(() => void)—Cancel, Escape or a scrim click: the value reverts to what it was when the picker opened (or was last accepted) — reported through `onChange` when it can be expressed (a date, or a range) — and this fires.
onChange((value: Date | DateRange) => void)—Fires with the new value (`Date` in single mode, `[start, end]` in range) on every pick — with the action row this is the draft; `onAccept` commits.
onClose((reason: DatePickerCloseReason) => void)—Modal only: the picker asks to close, with the reason (B7 vocabulary).
onModeChange((mode: DatePickerMode) => void)—Fires when the header toggle switches the display mode.
openboolean—Show the picker as a modal dialog (scrim, focus trap, Escape) — the Compose `DatePickerDialog` equivalent. Omit for an inline picker.
previousMonthLabelstringPrevious monthAccessible label of the previous-month button.
rangebooleanfalseSelect a start/end range instead of a single date.
selectYearLabelstringSelect yearAccessible name of the year picker list.
showModeTogglebooleantrueShow the header's calendar / text-input toggle (m3: date input via the edit icon).
startDateLabelstringStart dateRange start: cell prefix, headline placeholder and input label.
switchToCalendarLabelstringSwitch to calendar input modeAccessible label of the toggle while showing the text input.
switchToInputLabelstringSwitch to text input modeAccessible label of the toggle while showing the calendar.
titleLabelstring'Select date' ('Select dates' in range mode, 'Enter dates' for range input)Header title.
todayLabelstringTodayPrefix announced on today's cell.
valueDate | DateRange | null—Controlled value — a `Date` (single) or `[start, end]` (range).

DatePickerField​

PropTypeDefaultDescription
classNamestring—
defaultValueDate | null—Uncontrolled initial date.
dialogLabelstringChoose dateAccessible name of the calendar popup (`role="dialog"`).
disabledboolean—
getErrorLabel((error: DateInputError, pattern: string) => string)—Error message for rejected typed text. Defaults to Compose's English strings: "Date does not match expected pattern: MM/DD/YYYY" / "Date not allowed".
labelstringDateField label.
localestringen-USBCP-47 locale — display format, typed-date field order, week start.
maxDate—Latest selectable date.
minDate—Earliest selectable date.
nextMonthLabelstringNext monthAccessible label of the next-month button.
nextYearLabelstringNext yearAccessible label of the next-year button.
onChange((date: Date | null) => void)—Fires with the newly selected / committed typed date (or null when cleared).
openCalendarLabelstringOpen calendarAccessible label of the calendar toggle.
previousMonthLabelstringPrevious monthAccessible label of the previous-month button.
previousYearLabelstringPrevious yearAccessible label of the previous-year button.
selectMonthLabelstringSelect monthAccessible name of the month menu list.
selectYearLabelstringSelect yearAccessible name of the year menu list.
supportingTextstring—Helper text under the field. Defaults to the locale's input format (e.g. `MM/DD/YYYY`), as m3 accessibility asks.
todayLabelstringTodayPrefix announced on today's cell.
valueDate | null—Controlled selected date.