Browse project documentation
Values, events, and the public API
Store date-only values, handle events, and use the element's JavaScript and TypeScript APIs.
Values and time zones
value is a string representing a date or period, not an instant. For a day, 2026-03-15 means the Gregorian calendar day regardless of the display calendar. Keep it as a date-only value in your data model. Store range endpoints as separate dates when useful; week, multiple, and annotated period values need a schema appropriate to their shapes, not a single SQL DATE column.
Avoid converting a date-only string to a timestamp merely to store it. If your application needs an instant, it must choose a time and a time zone explicitly; the picker has no time-of-day or time-zone option.
valueAsDate is a convenience native Date at local midnight. It is null for empty, range, and multiple selection; month/year use the first day of the period. Week returns the ISO week’s Monday, which may differ from the configured locale week’s start. Prefer rangeStart and rangeEnd for week boundaries.
“Today” uses the runtime’s detected time zone, cached by the module. Today, relative presets, and disable-past/disable-future depend on that zone. The component refreshes today on rendering and interaction, not via a midnight timer. For a business cutoff in another zone, compute the allowed dates in your application and pass explicit bounds.
Non-Gregorian month/year values use the first Gregorian day plus [u-ca=...]. The annotation does not change calendar; use the matching calendar setting. See period formats. Display text is generated by Intl and can vary in punctuation or spacing between runtimes; do not parse it as a storage format.
Assigning and reading a value
import 'intl-datepicker';
const picker = document.querySelector('intl-datepicker');
picker.value = '2026-03-15';
console.log(picker.getValue().calendar); // { year: 2026, month: 3, day: 15 }
picker.setValue('2026-03-20');
console.log(picker.value); // 2026-03-20
picker.clear();
console.log(picker.value, picker.getValue()); // '', null
This example uses the default Gregorian date picker. Setting .value and calling setValue() use the same parser. Valid values normalize to the type’s format. An invalid assignment warns and keeps the previous selection; an invalid initial value leaves the selection empty. '' clears. Multiple values can discard invalid items rather than reject the whole list.
The value attribute sets the value silently and is also the reset default. Property/method updates do not reflect back to that attribute. For configuration without a public setter, use setAttribute() / removeAttribute(); picker.calendar = 'persian' is not a supported setter. HTML boolean attributes are enabled by their presence, so remove disabled rather than setting it to "false".
Events
Listen on the element with addEventListener(). All events bubble and cross shadow boundaries.
| Event | Payload and timing |
|---|---|
intl-select | SelectDetail after an accepted user selection, including a range start, typing, Today, or a preset |
intl-change | SelectDetail after user selection and changed .value / setValue() / clear() calls |
intl-navigate | NavigateDetail when user navigation changes the visible month window |
intl-open, intl-close | Cancelable events before opening/closing the popup; no application payload |
Repeated programmatic assignment of the same serialized value does not emit intl-change. User selection or preset activation can emit it even when the resulting string is unchanged. clear() emits change if needed but no select event, including when invoked by the clear button. Initial values, setAttribute('value', ...), configuration attribute changes, and form reset do not emit change. goToMonth() does not emit navigate.
import 'intl-datepicker';
const picker = document.querySelector('intl-datepicker');
picker.addEventListener('intl-change', ({ detail }) => {
console.log(detail.value);
if (detail.type === 'range' && detail.end === null) return;
// A completed selection or a clear can now update application state.
});
picker.setValue('2026-03-15'); // Logs 2026-03-15 if the previous value differed.
Use event.preventDefault() in intl-open or intl-close to cancel. Do not cancel close indiscriminately: that also prevents normal Escape dismissal. Inline calendars do not use popup open/close events.
Structured event details
Every SelectDetail includes type, value, and formatted.
| Type | Additional fields |
|---|---|
date | calendar: { year, month, day } or null |
range, week | start and end: active-calendar { year, month, day } objects or null |
multiple | dates: array of active-calendar { year, month, day } objects |
month | calendar: { year, month } or null; Gregorian ISO start/end strings or null |
year | calendar: { year } or null; Gregorian ISO start/end strings or null |
On clear, events carry an empty value, null scalar date fields, or an empty dates list. In contrast, getValue() returns null when empty. A pending range has a start and null end. Month/year bounds include the final day.
NavigateDetail contains year, month in the active calendar, direction (forward or backward), and Gregorian ISO start/end covering all visible month panels. It is not emitted on initial mount: load initial availability explicitly.
Public properties and methods
| API | Meaning |
|---|---|
value, type, name | Read/write value, picker mode, and form field name |
numerals, captionLayout, fixedWeeks | Read/write display properties reflecting attributes |
labels, presets | Object/array setters; runtime also accepts JSON strings |
mapDays, disabledDatesFilter | JavaScript callback setters; assign null to remove |
displayValue | Read-only localized display string |
calendarValue | Read-only selected CalendarDate for date/month/year, otherwise null |
rangeStart, rangeEnd | Read-only Gregorian ISO endpoints for range/week, otherwise null |
selectedDates | Read-only use of the multiple selection’s CalendarDate[] |
valueAsDate | Native Date convenience; see time-zone caveats above |
getValue() | Current structured detail or null |
setValue(string), clear() | Update or clear selection |
open(), close() | Popup controls; no effect in inline mode; opening is blocked while disabled |
goToMonth(year, month) | Show a month in the active calendar; month numbering starts at 1; call after connection |
form, validity, validationMessage, willValidate | Native form state through ElementInternals |
checkValidity(), reportValidity() | Check validity or also request browser feedback |
goToMonth() changes the view, not the selection, and does not clamp its arguments to min/max. Use calendar-aware values and keep the requested view within your bounds. Do not mutate returned calendar objects or arrays to update selection; use setValue().
TypeScript
import 'intl-datepicker';
import type { IntlDatepickerElement, SelectDetail } from 'intl-datepicker';
const picker: IntlDatepickerElement = document.createElement('intl-datepicker');
picker.type = 'month';
document.body.append(picker);
picker.addEventListener('intl-change', (event) => {
const detail: SelectDetail = event.detail;
if (detail.type === 'month' && detail.calendar) {
console.log(detail.calendar.month, detail.start, detail.end);
}
});
picker.setValue('2026-03');
The example logs 3, 2026-03-01, and 2026-03-31. Narrow SelectDetail by type before using type-specific fields, and handle cleared selections.
The declaration entry exports DatepickerType, DayOfWeekName, ExcludeDisabledMode, DateFormat, CaptionLayout, all six detail interfaces, SelectDetail, NavigateDetail, DayInfo, MapDaysInput, MapDaysResult, MapDaysFn, RangePreset, DisabledDatesFilterFn, IntlDatepickerLabels, PluralLabel, and IntlDatepickerEventMap. It augments element tag-name and event maps. React exports IntlDatepickerProps and IntlDatepickerRef.
Use IntlDatepickerElement as a type, not a runtime constructor. The runtime exports IntlDatepicker and register, but the current declarations do not declare those exports. Also, the element’s typed labels/presets setters accept objects/arrays only, although runtime accepts JSON strings. Prefer the documented side-effect import and object/array setters in TypeScript.