Date picker specification - IgniteUI/igniteui-webcomponents GitHub Wiki

Date-picker specification

Owned by

Team name: Astrea + Design and Web Development

Developer name: Bozhidara Pachilova

Designer name: Dilyana Dimova

Requires approval from:

  • Damyan Petev
  • Svilen Dimchevski

Signed off by:

  • Simeon Simeonov
  • Radoslav Mirchev

Revision history

Version Author Date Notes
- Radoslav Karaivanov 16-Feb-2024 Initial draft
- Radoslav Karaivanov 21-Feb-2024 Updated behaviors, ARIA and automation sections
1.0 Radoslav Karaivanov 15-Mar-2024 Finalized specification
1.1 Radoslav Karaivanov 22-Apr-2024 Added min, max constraint behavior
1.2 Radoslav Karaivanov 06-Jun-2024 Aligned dialog mode and focus behaviors with Angular version
1.3 Radoslav Karaivanov 25-Sep-2024 Added header-date slot
1.4 Bozhidara Pachilova 20-May-2025 Add new readonly behavior description
2.0 Radoslav Karaivanov 07-Aug-2026 Aligned the specification with the current implementation: blur-commit value semantics, validation message slots, defaultValue, async picker methods, CSS parts; restructured to the current specification template

Overview

The igc-date-picker is a composite editor for a single date value. The date can be typed into a masked text field or selected from a calendar that is presented either as a dropdown anchored to the field, or as a modal dialog.

The component composes igc-date-time-input for the text-entry surface and igc-calendar for the selection surface, and surfaces the relevant configuration of both through a single, flat API. It is a form-associated custom element: it participates in native form submission and constraint validation, exposes min, max and disabledDates constraints, and renders validation messages through dedicated slots.

Typical scenarios include:

  • Booking and scheduling forms: a date field with a minimum of "today" and a maximum booking horizon
  • Filtering and reporting: from/to date editors bound to a data source query
  • Registration forms: a date of birth field where typing is faster than navigating a calendar
  • Availability calendars: unavailable dates rendered as disabled and holidays highlighted as special dates

Key Features

  • Two presentation modes: a lightweight dropdown anchored to the input, or a modal dialog with a calendar header and action area
  • Masked text entry: the date can be typed through the input format of the underlying igc-date-time-input
  • Separate display format: predefined locale styles (short, medium, long, full) or a custom format string
  • Locale awareness: the input format, display format and all calendar strings are resolved from the active locale
  • Deferred value commit: typing never mutates the public value; the edit is committed - and igcChange emitted - when the editor is blurred
  • Non-editable and readonly modes: selection can be restricted to the calendar only, or the whole component can be frozen
  • Constraint validation: required, min, max and disabledDates validators plus setCustomValidity, with per-error message slots
  • Full calendar configuration: week start, week numbers, outside days, multiple visible months, orientation, special and disabled dates, active date
  • Form association: submits with the form, resets to defaultValue, and reacts to a disabled ancestor fieldset
  • Rich templating: clear and calendar icons, prefix/suffix content, calendar title, header date and an action area
  • Themeable: integrates with the theming system of the library and re-exports the shadow parts of the calendar it composes
  • Accessibility-first: dialog semantics for the picker, focus trapping while open, and full keyboard support

Acceptance criteria

The igc-date-picker must:

  • let users input a date by either typing it in or picking one through its calendar component.
  • be form associated and, when configured as part of a form, participate in form submission, reset and validation.
  • expose configuration properties for modifying/localizing the input and display format of the date value in the input part.
  • expose configuration properties for modifying/localizing the relevant parts of its calendar component.
  • present the calendar either as a dropdown or as a modal dialog, based on the mode property.
  • keep the public value free of intermediate editing state and emit igcChange only for committed values.
  • support restricting input to calendar selection only (non-editable) as well as freezing the whole component (readonly).
  • render dates outside the min/max range and inside disabledDates as disabled in the calendar, and invalidate the component when such a date is typed in.
  • correctly manage and report its validation state and render the corresponding validation message slots.
  • have adequate keyboard support for navigation and selection.
  • be integrated and themeable with the theming mechanism of the library.
  • be WAI-ARIA compliant.
  • support RTL layouts without additional configuration.

User stories

End-user stories

As an end-user I expect to be able to:

  • type in a date value inside the component.
  • select a date from the calendar picker of the component.
  • identify and distinguish the current date, the selected date, special and disabled dates.
  • see the selected date rendered in a readable, locale-appropriate way when I am not editing it.
  • clear a selected date with a single click.
  • navigate and make edits in the input part of the component using a keyboard.
  • navigate and make a selection in the calendar picker part of the component using a keyboard.
  • navigate in and out of the component using only a keyboard.
  • be told when the date I entered is required, too early, too late, or unavailable.

Developer stories

As a developer I expect to be able to:

  • set an initial value for the component and/or change the value of the component programmatically if need be.
  • set the interaction state of the component - make it disabled, readonly and/or non-editable.
  • set additional properties such as label, placeholder and/or validators in order to enrich and guide the end-user experience.
  • use the component in a standard form and have the component participate in form submission, reset and validation.
  • choose whether the calendar picker would be a dropdown like experience or a dialog like experience.
  • control how the date value would be formatted in the input both during editing and display, by specifying a custom pattern/mask.
  • rely on value reflecting only committed values, so that a two-way binding never clobbers a half-typed date.
  • observe the value as it is being typed through igcInput, and the committed value through igcChange.
  • hide/show days outside of the current month in the calendar picker.
  • set the day that weeks would start on in the calendar picker.
  • set whether to show/hide week numbers in the calendar picker.
  • set special/disabled dates in the calendar picker.
  • set the number of months rendered in the calendar picker.
  • set the formatting and localization of dates and elements in the calendar picker.
  • provide my own messages for each validation failure.
  • listen and react to user interactions through events on the component.

Functionality

The date picker is an input-like component with an attached calendar surface. Label, placeholder, helper text, prefix/suffix content and the validation visual states follow the conventions of the other input-like components of the library, while the calendar surface follows the conventions of igc-calendar.

End-user experience

Design Handoff

Visual structure

  • A single-line text field with an optional floating or static label, depending on the theme in use.
  • A calendar icon rendered in the prefix position which toggles the picker.
  • A clear icon rendered in the suffix position, present only while there is a value.
  • Optional prefix and suffix content rendered on either side of the text.
  • Optional helper text below the field, replaced by the relevant validation message when the component is invalid.
  • The calendar surface, rendered either in a popover anchored to the field (dropdown mode) or in a modal dialog (dialog mode). In dialog mode the calendar renders a header and, when action content is provided, a footer.

Opening and closing

  • Clicking the calendar icon toggles the picker in both modes.
  • Clicking the input opens the picker in dialog mode only - in dropdown mode the input is an editable field and a click positions the caret instead.
  • Clicking the label opens the picker in dialog mode only.
  • Alt + opens the picker, Alt + and Escape close it and return focus to the input.
  • Clicking outside the component closes the picker, unless keepOpenOnOutsideClick is set.
  • Selecting a date closes the picker and returns focus to the input, unless keepOpenOnSelect is set.

Selecting

  • When the picker is opened, focus is moved inside the calendar. If there is a selected value its corresponding calendar element is focused, otherwise the current active date of the calendar is focused.
  • Once focus is inside the calendar, subsequent keyboard navigation is trapped inside the calendar until the user selects a date, presses Escape, or clicks outside of the component.
  • Dates outside the min/max range and dates inside disabledDates are rendered as disabled and cannot be selected.
  • Selecting a date commits it immediately and emits igcChange.

Typing

  • Unfocused: the committed value is rendered through displayFormat, so it can be considerably more verbose than what the user types (for example Tuesday, July 9, 2024).
  • On focus: the text flips to the input format. An empty editor shows the empty mask (__/__/____) and selects it, so that typing immediately starts filling the first part.
  • While typing: only the mask positions accept input and literals are skipped over automatically. The calendar view follows along - typing a date in another month brings that month into view.
  • On blur: the edit is committed and igcChange is emitted if the committed value differs from the one the editor was focused with. A mask that cannot resolve to a valid date clears the value.

Feedback and accessibility

  • Focus indicator: the field shows the theme's focus styling; the inner native input is the focus target.
  • Screen readers: the input is a native text input with an associated label and aria-haspopup="dialog"; the calendar surface is exposed as a dialog labelled by the input.
  • Validation: the invalid state is applied after the component has been interacted with, and the matching validation message slot replaces the helper text. Opening the picker through the calendar icon does not, by itself, mark a required picker invalid.

Developer experience

The igc-date-picker component is designed for ease of integration with a declarative API that mirrors the rest of the input-like components in the library.

Basic initialization

The simplest picker requires no configuration at all - the input format, display format, placeholder and all calendar strings are derived from the active locale:

<igc-date-picker label="Start date"></igc-date-picker>

An initial value can be set as an ISO string through the attribute, or as a Date through the property:

<igc-date-picker label="Start date" value="2024-01-01"></igc-date-picker>
const picker = document.querySelector('igc-date-picker')!;
picker.value = new Date(2024, 0, 1);

Picker mode

The mode property selects the presentation of the calendar surface:

<!-- Anchored popover, editable input (default) -->
<igc-date-picker mode="dropdown"></igc-date-picker>

<!-- Modal dialog, read-only input -->
<igc-date-picker mode="dialog"></igc-date-picker>

The two modes differ in more than presentation:

  • In dialog mode the input part is always read-only and clicking anywhere on it - or on the label - opens the dialog.
  • In dropdown mode no calendar header is rendered. In dialog mode the header is rendered unless hide-header is set, and its orientation is controlled through header-orientation.
  • In dialog mode content projected in the title, header-date and actions slots is rendered in the dialog; the title and header-date slots have no effect in dropdown mode.
  • In dropdown mode the calendar is wrapped in a focus trap. In dialog mode focus trapping and the modal overlay are provided by the dialog itself, and keepOpenOnOutsideClick maps onto the dialog's outside-click behavior.

Input format

The inputFormat property is the mask the end-user edits, and is forwarded to the underlying igc-date-time-input. Every supported format character contributes an editable position; anything else is treated as a literal and skipped over while typing.

Format Description
d Day of the month, single position.
dd Day of the month with an explicitly set leading zero.
M Month, single position.
MM Month with an explicitly set leading zero.
yy Short (two digit) year format. Values below 50 resolve to the 2000s.
yyyy Full year format. Any year format other than yy is normalized to yyyy.
<igc-date-picker input-format="dd.MM.yyyy"></igc-date-picker>

Setting prompt changes the character used for the positions that are not filled in yet:

<igc-date-picker input-format="dd/MM/yyyy" prompt="*"></igc-date-picker>

Note

If inputFormat is not explicitly set, it defaults to the date-time input format resolved for the current locale.

Display format

While the input is not focused, the committed value is rendered through displayFormat. It accepts one of the predefined styles below - all examples are given for 2024-07-09 in the en locale - or a custom format string.

Format Result
short 7/9/24
medium Jul 9, 2024
long July 9, 2024
full Tuesday, July 9, 2024

A custom display format is built from the following symbols:

Token Description Result
d Day - minimum digits 9
dd Day - zero padded 09
M Month - minimum digits 7
MM Month - zero padded 07
MMM Month - Abbreviated Jul
MMMM Month - Full July
MMMMM Month - Narrow J
y Year - Numeric 2024
yy Year - Two digit short form 24
yyy Year - Numeric 2024
yyyy Year - Numeric 2024
<igc-date-picker
  locale="fr"
  input-format="dd/MM/yyyy"
  display-format="full"
></igc-date-picker>

Note

If displayFormat is not defined, the value of inputFormat is used, and if that is not defined either, the default date-time format of the current locale is used.

Note

The predefined styles are resolved as date-only styles by the date picker - short renders as 7/9/24, not as 7/9/24, 12:00 AM.

Value and commit semantics

The public value only ever holds a committed value. Calendar selection commits immediately. While the user is typing in the input, the intermediate state stays in the editor and the parsed result reaches value - together with an igcChange event - when the edit is committed on blur.

const picker = document.querySelector('igc-date-picker')!;

// Observe the value as it is being typed. The detail is the date currently in
// the editor, or `null` while the typed text cannot resolve to a date.
picker.addEventListener('igcInput', ({ detail }) => {
  console.log('typing:', detail);
});

// Observe committed values only - calendar selection, a committed edit, or a
// cleared value.
picker.addEventListener('igcChange', ({ detail }) => {
  console.log('committed:', detail); // Date | null
});

This is what makes the component safe to two-way bind: a host re-rendering with the value it last received from igcChange will not reset a half-typed date. Assigning a genuinely different value while the user is typing still wins and replaces the text.

The value accepts a Date, an ISO string, or null; the getter always returns a Date or null. An invalid date resolves to null:

picker.value = new Date(2024, 0, 1);
picker.value = '2024-01-01';
picker.value = null; // clears the picker

Assigning the value programmatically does not emit igcChange, and neither does clear().

Interaction states

State Input part Calendar picker Clear icon
Default (dropdown mode) Editable Can be toggled and selected in Active
mode="dialog" Read-only, click opens dialog Can be toggled and selected in Active
non-editable Read-only, click does not open Can be toggled and selected in Active
readonly Read-only Cannot be toggled or opened Inactive
disabled Disabled Cannot be toggled or opened Inactive
  • When non-editable is set, the input part of the component is transformed into a read-only field. Selection is still available through the calendar picker, and no igcInput events are emitted.
  • When readonly is set, the input part is transformed into a read-only field, keyboard shortcuts and toggling of the calendar picker are disabled, as is clearing the value. The calendar and clear icons appear visually disabled. If the picker is opened programmatically while readonly, a selection made in the calendar is reverted.
  • disabled removes the component from the tab order and from form submission entirely.

Constraint validation

min and max bound the valid range, disabledDates excludes individual dates or date ranges, and required makes an empty picker invalid. min, max and disabledDates are also applied to the calendar, which renders the corresponding dates as disabled so they cannot be selected. Validation messages are rendered through the per-error slots, replacing the helper text while the component is invalid.

<igc-date-picker
  label="Delivery date"
  required
  min="2024-08-01"
  max="2024-08-31"
>
  <span slot="helper-text">August only</span>
  <span slot="value-missing">Please pick a delivery date</span>
  <span slot="range-underflow">The date is before the delivery window</span>
  <span slot="range-overflow">The date is after the delivery window</span>
  <span slot="bad-input">This date is not available</span>
</igc-date-picker>
picker.disabledDates = [
  { type: DateRangeType.Specific, dateRange: [new Date(2024, 7, 15)] },
  { type: DateRangeType.Weekends, dateRange: [] },
];

When the input is editable, typing a date that falls inside disabledDates invalidates the component and is reported through the bad-input slot.

Note

This is more of a fringe scenario as in that case making the input non-editable and allowing the user to make a selection through the calendar widget is a better UX.

Custom constraints are applied through setCustomValidity, and reported through the custom-error slot:

picker.addEventListener('igcChange', ({ detail }) => {
  const isHoliday = detail ? isPublicHoliday(detail) : false;
  picker.setCustomValidity(
    isHoliday ? 'Public holidays are not available' : ''
  );
});

Configuring the calendar

The calendar-related configuration is surfaced directly on the picker and forwarded to the composed igc-calendar:

<igc-date-picker
  week-start="monday"
  show-week-numbers
  hide-outside-days
  visible-months="2"
  orientation="horizontal"
  active-date="2024-07-01"
></igc-date-picker>
picker.specialDates = [
  { type: DateRangeType.Specific, dateRange: [new Date(2024, 11, 24)] },
];

activeDate sets the date that is brought into view and highlighted. When it is not set, the picker opens on the selected value, and on the current date when there is no value either.

Slots and templating

<igc-date-picker label="..." mode="dialog" display-format="yyyy/MM/dd">
  <igc-icon slot="calendar-icon" name="calendar"></igc-icon>
  <igc-icon slot="calendar-icon-open" name="calendar_open"></igc-icon>
  <igc-icon slot="clear-icon" name="clear"></igc-icon>
  <span slot="prefix">from</span>
  <span slot="helper-text">Pick a start date</span>
  <p slot="title">Select a start date</p>
  <igc-button slot="actions" @click="${...}">Set today</igc-button>
</igc-date-picker>

Programmatic control

const picker = document.querySelector('igc-date-picker')!;

// Picker state. All three are asynchronous and resolve with whether the state
// actually changed. They do not emit the opening/closing events.
await picker.show();
await picker.hide();
await picker.toggle();

// Value
picker.clear();

// Step the date part currently under the caret in the input
picker.stepUp();
picker.stepDown(DatePart.Month, 3);

// Selection and text manipulation in the input part
picker.select();
picker.setSelectionRange(0, 2);
picker.setRangeText('12', 0, 2);

// Validation
picker.setCustomValidity('Not available');
picker.checkValidity();
picker.reportValidity();

Form integration

The component is a form-associated custom element, so it needs no wrapper component to participate in a form:

<form>
  <igc-date-picker name="start-date" required></igc-date-picker>
  <button type="submit">Submit</button>
  <button type="reset">Reset</button>
</form>
  • The value is submitted under name as an ISO string; an empty picker is not submitted.
  • Enter inside the input submits the owning form, unless the picker is invalid.
  • A form reset restores defaultValue. Setting the value attribute sets the default value, while assigning the value property does not.
  • A disabled ancestor fieldset disables the picker.
// Reset target, independent of the current value
picker.defaultValue = new Date(2024, 0, 1);

Localization

Everything locale-dependent is derived from the active locale:

  • inputFormat defaults to the locale's date input pattern, so the order of the day, month and year parts follows the locale.
  • placeholder defaults to the resolved input format.
  • displayFormat falls back to inputFormat and then to the locale's default format; the predefined styles as well as the month and weekday names are rendered through the locale's data.
  • The calendar strings - month and weekday names, the navigation and selection labels - come from the localization resources.

The locale property overrides the locale for a single picker; when it is not set, the picker follows the library's global locale. A runtime change of the global locale or of the localization resources re-resolves the default format and re-renders both the input and the calendar.

<igc-date-picker locale="ja"></igc-date-picker>

The resourceStrings property overrides individual strings for a single picker. It accepts the calendar resource strings as well as the picker's own strings, which are used for the title of the calendar icon and the label of the dialog:

Key Default (en)
date_picker_choose_date Choose date
date_picker_change_date Change date
calendar_select_date Select date

Validation messages are provided by the application through the validation message slots and are therefore localized by the application.

Keyboard interactions

As long as focus is within any part of the date picker:

Key combination Result
Escape If the picker is shown, closes the picker and returns focus to the input part. Otherwise it is a no-op.

When the input part of the component is focused:

Key combination Result
/ Moves the caret one position to the left/right.
Home / End Moves the caret to the beginning/end of the mask.
Ctrl / Cmd + Moves the caret to the beginning of the current date section, or of the previous one.
Ctrl / Cmd + Moves the caret to the end of the current date section, or of the next one.
Increments the date part the caret is in.
Decrements the date part the caret is in.
Ctrl / Cmd + ; Sets the current date as the value of the component.
Alt + Opens the calendar picker.
Alt + Closes the calendar picker and returns focus to the input part.
Enter Submits the owning form, if any and if the picker is valid.

All of the above are no-ops when the component is readonly or disabled; the editing subset is additionally a no-op when the component is non-editable or in dialog mode.

When focus is within the calendar picker, the keyboard navigation follows the behaviors described in this section of the calendar specification.

API

Properties and attributes

Property Attribute Reflected Type Default Description
value value No Date | string | null null The committed value of the picker. Accepts a Date or an ISO string; always returns a Date or null.
defaultValue - - Date | string | null null The value the picker reverts to on form reset. Also set by the value attribute.
open open Yes boolean false Whether the calendar picker is open.
mode mode No 'dropdown' | 'dialog' dropdown Whether to display the calendar picker in a dropdown or in a modal dialog.
keepOpenOnSelect keep-open-on-select Yes boolean false Whether the calendar picker should be kept open on selection.
keepOpenOnOutsideClick keep-open-on-outside-click Yes boolean false Whether the calendar picker should be kept open when clicking outside of it.
label label No string - The label of the picker.
placeholder placeholder No string mask The placeholder text of the input part. Defaults to the resolved input format.
inputFormat input-format No string locale Date mask pattern applied while editing in the input part. Reference
displayFormat display-format No string inputFormat Date pattern applied to the input value while the input is not focused. Reference
prompt prompt No string _ The prompt character used for the unfilled positions of the input mask.
locale locale No string global The locale used for the input/display formats and the calendar. Falls back to the library's global locale (en).
resourceStrings - - IgcCalendarResourceStrings en resources Resource strings for the localization of the picker and its calendar.
min min No Date | string | null null The minimum value required for the picker to remain valid.
max max No Date | string | null null The maximum value allowed for the picker to remain valid.
disabledDates - - DateRangeDescriptor[] - The disabled dates of the calendar picker. Also participate in validation.
specialDates - - DateRangeDescriptor[] - The special dates of the calendar picker.
activeDate active-date No Date | string | null current date The date which is shown in view and highlighted in the calendar picker.
weekStart week-start No WeekDays sunday The start day of the week for the calendar picker.
showWeekNumbers show-week-numbers Yes boolean false Whether to show the number of the week in the calendar days view.
hideOutsideDays hide-outside-days Yes boolean false Whether to hide the dates that do not belong to the current month.
hideHeader hide-header Yes boolean false Whether the calendar hides its header. Applicable only in dialog mode.
headerOrientation header-orientation Yes 'vertical' | 'horizontal' horizontal Whether to align the calendar header vertically or horizontally. Applicable only in dialog mode.
orientation orientation No 'vertical' | 'horizontal' horizontal Whether to align multiple months horizontally or vertically.
visibleMonths visible-months No number 1 The number of months to show in the calendar days view.
nonEditable non-editable Yes boolean false Whether to disallow typing in the input part.
readOnly readonly Yes boolean false Makes the component a readonly field.
outlined outlined Yes boolean false Whether the input part will have an outlined appearance.
disabled disabled Yes boolean false The disabled state of the component.
required required Yes boolean false Makes the component a required field for validation.
invalid invalid No boolean false Sets the control into invalid state (visual state only).
name name Yes string - The name of the control, submitted with the form data.
form - - HTMLFormElement | null - Read-only. The form this element is associated with.
validity - - ValidityState - Read-only. The validity states of the element.
validationMessage - - string - Read-only. The validation message of the element.
willValidate - - boolean - Read-only. Whether the element is a candidate for constraint validation.

Methods

Name Type signature Description
show (): Promise<boolean> Shows the calendar picker. Resolves with whether the state changed. Does not emit the opening events.
hide (): Promise<boolean> Hides the calendar picker. Resolves with whether the state changed. Does not emit the closing events.
toggle (): Promise<boolean> Toggles the open state of the calendar picker. Does not emit the opening/closing events.
clear (): void Clears the input part of the component of any user input and sets the value to null.
stepUp (datePart?: DatePart, delta?: number): void Increments the passed in date part of the input part.
stepDown (datePart?: DatePart, delta?: number): void Decrements the passed in date part of the input part.
select (): void Selects the text in the input of the component.
setSelectionRange (start: number, end: number, direction?: SelectionRangeDirection): void Sets the text selection range in the input of the component.
setRangeText (replacement: string, start: number, end: number, mode?: RangeTextSelectMode): void Replaces the selected text in the input, re-applies the mask and commits the result to the value.
setCustomValidity (message: string): void Sets a custom validation message. As long as message is not empty, the component is considered invalid.
checkValidity (): boolean Checks the validity of the control and emits the invalid event if it is invalid.
reportValidity (): boolean Checks the validity of the control and shows the browser message if it is invalid.

DatePart is an enum with the members Date, Month, Year, Hours, Minutes, Seconds and AmPm; only the date members are meaningful for this component.

Events

Name Cancellable Detail Description
igcOpening Yes - Emitted just before the calendar picker is shown.
igcOpened No - Emitted after the calendar picker is shown.
igcClosing Yes - Emitted just before the calendar picker is hidden.
igcClosed No - Emitted after the calendar picker is hidden.
igcInput No Date | null Emitted while the user is typing in the input part. The detail is the date currently in the editor, or null while it cannot resolve to one.
igcChange No Date | null Emitted when the user commits a value - through calendar selection, or when a typed edit is committed.
invalid Yes - Emitted when the control is found invalid during a validation cycle.

The open/close events are emitted only for user interactions and for the internal close paths - the show, hide and toggle methods change the state silently.

Slots

Name Description
prefix Renders content before the input.
suffix Renders content after the input.
helper-text Renders content below the input.
clear-icon Renders a clear icon template.
calendar-icon Renders the icon/content for the calendar picker in closed state.
calendar-icon-open Renders the icon/content for the calendar picker in open state.
title Renders content in the calendar title. Applicable only in dialog mode.
header-date Renders content instead of the current date in the calendar header. Applicable only in dialog mode.
actions Renders content in the action part of the picker in open state.
value-missing Renders content when the required validation fails.
range-overflow Renders content when the max validation fails.
range-underflow Renders content when the min validation fails.
bad-input Renders content when the value falls inside the disabledDates ranges.
custom-error Renders content when setCustomValidity(message) is set.
invalid Renders content when the component is in invalid state.

CSS Shadow parts

Part Description
label The label wrapper that renders content above the target input.
input The native input element.
prefix The prefix wrapper.
suffix The suffix wrapper.
calendar-icon The calendar icon wrapper for closed state.
calendar-icon-open The calendar icon wrapper for opened state.
clear-icon The clear icon wrapper.
actions The actions wrapper.
helper-text A helper-text wrapper that renders content below the target input.
dialog-base The base wrapper of the dialog. Applicable only in dialog mode.
title The title of the dialog. Applicable only in dialog mode.
footer The footer of the dialog. Applicable only in dialog mode.
overlay The overlay of the dialog. Applicable only in dialog mode.

Note

All CSS Parts of the Calendar component can also be used to style the igc-date-picker. Keep in mind that the content and the label parts of the calendar component are renamed respectively to calendar-content and calendar-label in the igc-date-picker scope.

Assumptions and limitations

  • Only a single date value is edited per component; ranges are covered by igc-date-range-picker and time-only editing by igc-date-time-input.
  • The value is a local Date; time zones are not modelled.
  • Although the input part is an igc-date-time-input, the picker is a date-only editor. Time tokens in the input format are not part of the supported configuration.
  • The input format is positional. Variable-width tokens that are valid in a display format - MMM, MMMM - are not supported as input format tokens.
  • Two-digit years below 50 resolve to the 2000s; 50 and above resolve to the 1900s.
  • min, max and disabledDates restrict the calendar and drive validation, but they do not prevent an out-of-range date from being typed in - such a value invalidates the component instead.
  • The container part of the underlying input is not re-exported by the picker.
  • hideHeader, headerOrientation, and the title and header-date slots are only in effect in dialog mode.

Test scenarios

Rendering and Initialization

  1. Default rendering

    • The component is defined and rendered in the DOM
    • The default mask, prompt and placeholder for the active locale are applied to the input part
    • value is null, the picker is closed and no validation styling is applied
    • The label renders through the input part in the Material theme and through the picker itself in the other themes
  2. Initial value

    • Setting the value attribute to an ISO string initializes the value and the displayed text
    • Setting the value property to a Date initializes the value and the displayed text
    • Setting the value property to a string initializes the value
    • An invalid Date object is not set as a value, neither through the attribute nor through the property
  3. Initial open state

    • The component initializes in open state in dropdown mode
    • The component initializes in open state in dialog mode
  4. Slotted content

    • The prefix, suffix, clear-icon, calendar-icon, calendar-icon-open, helper-text, title, header-date and actions slots render their content
    • The title and header-date slot content is not rendered in dropdown mode
    • The clear icon is rendered only while there is a value

Picker Modes

  1. Dropdown mode

    • The input part stays editable
    • No calendar header is rendered
    • The calendar is wrapped in a focus trap while open
    • Clicking the input does not open the picker
    • Clicking the label does not open the picker
  2. Dialog mode

    • The underlying input is set into readonly mode
    • Clicking the input opens the dialog
    • Clicking the label opens the dialog
    • The calendar header is rendered unless hideHeader is set, and follows headerOrientation
    • Action content is projected into the dialog footer
  3. Open state configuration

    • The picker is shown/hidden based on the value of the open attribute
    • The picker is kept open on selection when keepOpenOnSelect is set
    • The picker is kept open on an outside click when keepOpenOnOutsideClick is set
    • The picker is closed on an outside click by default
    • Selecting a date closes the picker and returns focus to the input by default

Input and Display Format

  1. Format resolution
    • inputFormat defaults to the format resolved for the current locale
    • Setting inputFormat explicitly overrides the locale default
    • displayFormat renders the value while the input is not focused
    • The predefined display formats render as date-only styles
    • displayFormat falls back to inputFormat, and then to the locale default, when not set
    • prompt is applied to the unfilled positions of the mask
    • The relevant properties are forwarded to the underlying input part

Value and Commit Semantics

  1. Uncommitted edits

    • Typing in the input does not mutate value
    • igcInput exposes the typed date while value stays put
    • A host re-applying the bound value mid-edit does not reset the text
    • A genuinely different value assigned while typing replaces the text
  2. Commit

    • A committed edit updates value and emits a single igcChange
    • A calendar selection updates value and emits igcChange immediately
    • Text that cannot resolve to a valid date commits null
    • No igcChange is emitted for a programmatic value assignment
    • igcChange is emitted in dialog mode after clearing the value and losing focus
    • The calendar view follows the typed value, switching to another month when needed

Interaction States

  1. Non-editable

    • The value can be modified only through calendar selection
    • Typing in the input is a no-op and emits no igcInput
  2. Readonly - dropdown mode

    • The picker is not shown on a calendar icon click
    • The picker is not shown on the keyboard shortcut
    • The value is not cleared by clicking the clear icon
    • The value is not modified through typing or calendar selection
  3. Readonly - dialog mode

    • The dialog is not shown on a calendar icon click
    • The dialog is not shown on a label click
    • The dialog is not shown on an input click
    • The dialog is not shown on the keyboard shortcut
    • The value is not cleared by clicking the clear icon
  4. Disabled

    • The component is removed from the tab order and does not open
    • The component does not participate in form submission

Calendar Configuration

  1. Forwarded configuration

    • weekStart, showWeekNumbers, hideOutsideDays, visibleMonths, orientation, specialDates, disabledDates and locale are applied to the calendar
    • Dates outside min/max and inside disabledDates render as disabled and cannot be selected
  2. Active date

    • activeDate initializes to the current date when neither it nor the value is set
    • activeDate initializes to the value when it is not set but a value is
    • Setting activeDate brings the corresponding month into view and highlights the date

Keyboard Navigation

  1. Picker toggling and focus

    • Alt + opens and Alt + closes the picker in dropdown mode
    • Alt + opens and Alt + closes the picker in dialog mode
    • Escape closes an open picker and returns focus to the input
    • Focus moves to the selected date, or to the active date, when the picker is opened
    • Keyboard navigation is trapped inside the calendar while the picker is open
  2. Editing shortcuts

    • Caret movement and section jumps behave as specified
    • / step the date part under the caret
    • Ctrl / Cmd + ; sets the current date as the value

Methods

  1. Picker and value methods
    • show(), hide() and toggle() change the open state and do not emit the opening/closing events
    • clear() clears the input part and the value
    • stepUp() and stepDown() are delegated to the underlying input
    • select() selects the text in the input
    • setSelectionRange() sets the text selection range in the input
    • setRangeText() replaces the selected text, re-applies the mask and updates the value

Validation

  1. Constraints

    • required invalidates an empty picker and validates a filled one
    • min invalidates values before it, for both Date and string bindings
    • max invalidates values after it, for both Date and string bindings
    • A date inside disabledDates typed into the input invalidates the component
    • setCustomValidity() invalidates the picker while the message is not empty
    • checkValidity() and reportValidity() report the expected result and emit invalid when appropriate
    • Clicking the calendar toggle part does not put a required picker into invalid state
    • Validation is applied synchronously on a value change
  2. Validation message slots

    • value-missing, range-underflow, range-overflow, bad-input and custom-error content renders for the corresponding failure
    • invalid slot content renders while the picker is invalid
    • Validation messages replace the helper text and are cleared when the picker becomes valid
    • The projected messages render on the first failed form submission and persist afterwards

Form Integration

  1. Submission and reset
    • The element is form associated
    • An empty or invalid picker does not participate in form submission
    • A valid picker is submitted under its name
    • Enter submits the owning form when the value is valid, and does not when it is invalid
    • A form reset restores defaultValue
    • Setting the value attribute updates the default value used on reset
    • defaultValue participates in required, min and max validation
    • The picker reflects a disabled ancestor fieldset

Localization

  1. Locale-driven behavior
    • The input and display formats follow the locale
    • The calendar month, weekday and navigation strings follow the locale
    • resourceStrings overrides individual strings
    • A runtime locale or resource change re-renders both the input and the calendar

Accessibility

  1. Automated and semantic checks
    • The component passes automated WAI-ARIA tests in closed state
    • The component passes automated WAI-ARIA tests in open state in dropdown mode
    • The component passes automated WAI-ARIA tests in open state in dialog mode
    • The calendar surface is exposed as a dialog labelled by the input part
    • The input part advertises the popup through aria-haspopup
    • Helper text and validation messages are referenced through aria-describedby

RTL Support

  1. Right-to-Left
    • The component renders and edits correctly in an RTL context
    • The picker is positioned correctly in an RTL context
    • Caret navigation and section jumps behave correctly in RTL

Edge Cases

  1. Invalid configuration and rapid interaction
    • An invalid min/max value is ignored rather than throwing
    • min greater than max behaves predictably
    • Rapid typing, opening/closing and focus changes do not desynchronize the input, the calendar and the value
    • Leap years and month-length changes are handled when stepping the year and month parts

Accessibility

ARIA roles and properties

  • The editable surface is a native <input type="text">, so its value, label, description and invalid state are announced natively. The component sets delegatesFocus, so focusing the host focuses the inner input.
  • The input part carries aria-haspopup="dialog", advertising the calendar surface.
  • The calendar element carries role="dialog" and is labelled by the input part through aria-labelledby, in both dropdown and dialog mode.
  • In dialog mode the dialog additionally carries an aria-label describing the action - choose date or change date, depending on whether a value is already set.
  • While the picker is closed the calendar surface is inert, so it is not reachable by keyboard or exposed to assistive technology.
  • When helper text or a validation message is rendered, the input part references it through aria-describedby.
  • The disabled and readonly states are set on the inner input, so they are exposed natively.
  • The invalid state is exposed through the element's ElementInternals validity, so assistive technology is notified of a failed constraint.

References

https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/datepicker-dialog/

Keyboard support

Already covered by the relevant section of the specification.

Right to Left support

The date picker should work in a Right-To-Left context without additional setup or configuration.

⚠️ **GitHub.com Fallback** ⚠️