# DatePicker A button or text field that picks one date from a Calendar in a popover. ```ehtml Example import { DatePicker } from "@elements/ui/date-picker"; ``` ## Parts | Part | What it is | |---|---| | `DatePicker` | The picker: a trigger, a Popover with a Calendar, and a hidden input with the ISO value for the form. | | `.date-picker-trigger` | The button (button mode). Its width holds across every date. | | `.date-picker-input` | The text field (input mode): the locale's numeric format or ISO. | | `.date-picker-button` | The calendar button inside the text field (input mode). | | `.date-picker-content` | The popover panel: a dialog named by calendarLabel. | | `.date-picker-footer` | The footer slot under the calendar. | | `.date-picker-value` | The hidden input: name, required and validity. Beside the control with data-field-input, so a Field validates it; the only field the picker submits. | | `.date-picker-actions` | Cancel and OK under the calendar (actions). | ## Attributes | Attribute | Type | Default | Description | |---|---|---|---| | `value` | `ISODate` (two-way) | `""` | The date, "YYYY-MM-DD". | | `open` | `boolean` (two-way) | `false` | Whether the calendar is showing. | | `placeholder` | `string` | `""` | Shown without a value: "Pick a date" for the button, the format hint for the field. | | `format` | `Intl.DateTimeFormatOptions` | `{ dateStyle: "long" }` | How the button shows the date. | | `locale` | `string` | `""` | BCP 47 tag for the text, the calendar and typed dates. | | `numerals` | `string` | `""` | Numbering system for the text and the calendar. | | `calendar` | `string` | `""` | An Intl calendar (persian, hebrew, ...) for the calendar, the text and typed dates; the value stays a Gregorian ISO date. | | `timeZone` | `string` | `""` | An IANA time zone ("Pacific/Auckland"): today is the date there. Dates stay plain ISO days. | | `input` | `boolean` | `false` | A text field you can type into, with a calendar button. | | `natural` | `boolean` | `false` | Input mode reads English phrases: tomorrow, in 3 days, next friday, dec 25. The text stays as typed. | | `clearOnInvalid` | `boolean` | `false` | Input mode: while the text is not an allowed date, the value is empty (the text stays). For a field driving an inline calendar. | | `actions` | `boolean` | `false` | Cancel and OK under the calendar: OK picks the focused day (APG date picker dialog). | | `okLabel, cancelLabel` | `string` | `"OK", "Cancel"` | The actions' text. | | `yearButtons` | `boolean` | `false` | Previous and next year buttons in the calendar. | | `help` | `string` | `""` | Keyboard help announced once focus rests on a day. | | `name` | `string` | `""` | Form name; the form gets the ISO date. | | `form` | `string` | `""` | The id of a form elsewhere on the page. | | `required` | `boolean` | `false` | The form will not submit without a date. | | `disabled` | `boolean` | `false` | Not interactive; not submitted. | | `readOnly` | `boolean` | `false` | Shows the date and stays focusable (data-readonly); never opens. Not required, as a native read-only input. | | `invalid` | `boolean` | `false` | aria-invalid and the danger border. | | `invalidMessage` | `string` | `"Enter a valid date."` | The form's message for typed text that is not an allowed date. | | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Height and text from the control tokens. | | `block` | `boolean` | `false` | Full width. | | `label` | `string` | `""` | Accessible name without a visible label; the button appends the date. | | `calendarLabel` | `string` | `"Choose date"` | Names the popover dialog and the calendar button. | | `changeLabel` | `string` | `""` | Input mode: the calendar button's name once a date is set, "Change Date, ``". | | `icon` | `boolean` | `true` | A calendar icon in the button. | | `min` | `ISODate` | `""` | Earliest date: earlier days disabled, navigation bounded, typed dates refused. | | `max` | `ISODate` | `""` | Latest date. | | `disabledDates` | `Matcher \| Matcher[]` | `false` | Days that cannot be picked (Calendar matchers). | | `modifiers` | `Record` | `{}` | Calendar custom modifiers. | | `captionLayout` | `"label" \| "dropdown" \| "dropdown-months" \| "dropdown-years"` | `"label"` | Month and year dropdowns in the calendar. | | `numberOfMonths` | `number` | `1` | Months in the popover. | | `showOutsideDays, fixedWeeks, showWeekNumber, weekStartsOn, isoWeek, startMonth, endMonth, today, dir` | `as Calendar` | `as Calendar` | Passed to the Calendar. | | `month` | `ISODate` | `""` | The month each open starts on; empty starts on the picked date. Browsing never writes it back. | | `defaultMonth, hidden, navLayout, hideNavigation, disableNavigation, reverseMonths, reverseYears, hideWeekdays, firstWeekContainsDate, broadcastCalendar, animate, labels, formatters` | `as Calendar` | `as Calendar` | Passed to the Calendar. labels translates the month buttons, dropdowns and day names. | | `closeOnSelect` | `boolean` | `true` | Picking a day, or clicking the picked day to clear it, closes the popover. | | `side` | `"top" \| "right" \| "bottom" \| "left" \| "inline-start" \| "inline-end"` | `"bottom"` | Where the popover opens. | | `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment against the trigger. | | `modal` | `boolean` | `false` | Focus trapped in the popover, the page hidden from assistive tech. | | `class` | `string` | `""` | Classes on the root. | | `attrs` | `Record` | `{}` | Attributes for the button (or the text field in input mode): id, aria-\*, data-\*. | | `onValueChange` | `(value: ISODate) => void` | `() => {}` | The picker changed the value. | | `onOpenChange` | `(open: boolean) => void` | `() => {}` | The picker opened or closed itself. | | `onDayClick` | `(date, modifiers, e) => void` | `() => {}` | From the Calendar. | | `onMonthChange` | `(month: ISODate) => void` | `() => {}` | From the Calendar: the shown month changed. | ## Slots | Slot | Content | |---|---| | `footer` | Under the calendar in the popover: presets, a TimePicker, actions. | ## Keyboard | Keys | Action | |---|---| | `Enter / Space` | On the button: opens the calendar on the selected day, else today. | | `ArrowDown` | In the text field: opens the calendar. | | `Enter` | In the text field: commits the typed date, then the form submits it. | | `Arrows, PageUp / PageDown, Home / End` | Move through the calendar (see Calendar). | | `Enter / Space on a day` | Picks it, closes and returns focus to the button. | | `Escape` | Closes without a change and returns focus. | ## Data attributes | Attribute | Values | On | |---|---|---| | `data-mode` | `"button" \| "input"` | root | | `data-state` | `"open" \| "closed"` | root, trigger | | `data-empty` | present without a value | .date-picker-trigger | | `data-readonly` | present with readOnly | .date-picker-trigger | ## Accessibility - The trigger has aria-haspopup="dialog", aria-expanded and aria-controls; the popover is a dialog named by calendarLabel. - In input mode the calendar button is named "Choose date, October 14, 2026", and the field is described by the format hint (APG date picker dialog). - Typed text that is not an allowed date sets aria-invalid on blur and a custom validity, so the form will not submit. - Picking a day or pressing Escape returns focus to the trigger. - The hidden value input is aria-hidden and out of the Tab order; when the browser reports it, focus goes to the visible control. ## See also - [Calendar](calendar): A month grid for picking one date, several dates or a range, with keyboard navigation across months. - [DateRangePicker](date-range-picker): A button that picks a start and end date from a two-month range Calendar in a popover. - [TimePicker](time-picker): A time of day in the browser's own time field, styled as a control, with steps, limits and suggestions.