Date Picker
Masked date input that opens a Kikita calendar in a dropdown.
Date Picker composes the directive, Field, Dropdown, and Calendar public APIs.
import {
KuiCalendar,
KuiDatePicker,
KuiDropdown,
KuiField,
} from '@kikita-labs/ui';Place a kui-calendar in a dropdown next to the input inside the same kui-field: the directive wires value, viewDate, minDate and maxDate into it, so a clicked day updates the input and a typed date moves the calendar.
<div class="basic-date-picker-example">
<kui-field
label="Meeting date"
hint="Type the date in your locale's layout or choose from the calendar."
>
<input kuiDatePicker [(value)]="meetingDate" [minDate]="minDate" [maxDate]="maxDate" />
<kui-dropdown panelRole="dialog" panelWidth="auto" maxHeight="420px">
<kui-calendar flat showFooter />
</kui-dropdown>
</kui-field>
</div> Manual binding of value, viewDate and the bounds on the calendar still works and is not deprecated; both patterns converge on the same state without looping.
<!-- Still supported: bind the calendar yourself (not deprecated) -->
<kui-field label="Meeting date">
<input kuiDatePicker [(value)]="date" [(viewDate)]="viewDate" />
<kui-dropdown panelRole="dialog" panelWidth="auto" maxHeight="420px">
<kui-calendar flat [(value)]="date" [(viewDate)]="viewDate" showFooter />
</kui-dropdown>
</kui-field>Text is parsed and formatted with the numeric layout of the locale, or with the format input.
<div class="date-picker-format-example">
<kui-field label="Locale layout" hint="Follows the locale of the nearest i18n level.">
<input kuiDatePicker [(value)]="localeDate" />
<kui-dropdown panelRole="dialog" panelWidth="auto" maxHeight="420px">
<kui-calendar flat />
</kui-dropdown>
</kui-field>
<kui-field label="Pinned layout" hint="format pins dd.MM.yyyy whatever the locale is.">
<input kuiDatePicker format="dd.MM.yyyy" [(value)]="pinnedDate" />
<kui-dropdown panelRole="dialog" panelWidth="auto" maxHeight="420px">
<kui-calendar flat />
</kui-dropdown>
</kui-field>
</div>- The layout follows the locale of the nearest i18n level:
10/03/2026inen-US,03.10.2026inru-RUand2026/10/03inja-JP. The placeholder is built from thedayPlaceholder,monthPlaceholderandyearPlaceholdermessages in the same order and separators. formattakesd/dd,M/MMandyyyytokens such asdd.MM.yyyyand resolves as the input, thendefaults.datePicker.format, then the locale.- Parsing reads three digit groups in the layout's order, so
3.1.2026is accepted where03.01.2026is shown. Surrounding whitespace is trimmed and four-digit years from0000through9999are preserved.
minDate and maxDate are inclusive local calendar-day boundaries; their time portions are ignored, like kui-calendar.
- Typing an out-of-format value sets
aria-invalidanddata-kui-invalidwithout replacing the last parsedvalue. - A parseable date outside the bounds updates
valueandviewDateto the typed date but keeps the field invalid, while the linked calendar disables the cells outside the range. Typing a valid in-range date clears the invalid state. readonlyshows the value but never opens the popover;clearabledefaults to true and shows a clear button once there is a value.
The dropdown hosts a calendar grid, so its role and width strategy differ from select-like listboxes.
- Use
panelRole="dialog"because the panel contains a calendar grid. - Use
panelWidth="auto"so the panel keeps the calendar's own fixed width instead of stretching to the field's width. - Use
maxHeightas a viewport safety cap for constrained spaces. - The panel is wider than the field on purpose: the calendar has a fixed width (
--kui-calendar-width, 296px) thatpanelWidth="auto"keeps. - Use
flaton the calendar to avoid a double border inside the dropdown panel.
Set defaults.datePicker once for the application or for a subtree. Each option resolves as local input > defaults.datePicker.<option> > built-in default.
import { provideKikitaUi } from '@kikita-labs/ui';
export const appConfig: ApplicationConfig = {
providers: [
provideKikitaUi({
defaults: {
datePicker: {
/* options below */
},
},
}),
],
};| Name | Type | Default | Description |
|---|---|---|---|
| clearable | boolean | — | When true, field controls with clear affordances show a clear button by default. |
| chevronIcon | KuiIconGlyph | — | Icon of the options toggle. Takes precedence over defaults.icons.pickerChevron. See Structural Icons. |
| clearIcon | KuiIconGlyph | — | Icon of the clear button. Takes precedence over defaults.icons.clear. See Structural Icons. |
Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-date-picker-chevron-color-expanded | CSS custom property | --kui-color-primary-text | Chevron color, expanded |
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-date-picker-control-overlay-padding-inline | CSS custom property | --kui-space-3 | Control overlay padding, inline |
| --kui-date-picker-padding-inline-start | CSS custom property | 34px | Input start padding that clears the calendar icon |
| --kui-date-picker-padding-inline-end | CSS custom property | 34px | Input end padding that clears the chevron |
| --kui-date-picker-padding-inline-end-clearable | CSS custom property | 56px | Input end padding that clears the clear button and the chevron |
Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.
| Name | Type | Default | Description |
|---|---|---|---|
| openCalendar | string | — | Name of the button that opens the calendar. Default Open calendar. |
| closeCalendar | string | — | Name of the button that closes the calendar. Default Close calendar. |
| dayPlaceholder | string | — | Placeholder token for the day field. Default dd. |
| monthPlaceholder | string | — | Placeholder token for the month field. Default mm. |
| yearPlaceholder | string | — | Placeholder token for the year field. Default yyyy. |
Directive inputs, outputs, provider defaults, messages and paired calendar composition verified against @kikita-labs/ui v2.0.0 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| input[kuiDatePicker] | Directive | - | Turns a native text input into a masked date picker trigger. |
| [(value)] | Date | null | null | Selected date. Bind the same signal to the paired calendar. |
| [(viewDate)] | Date | current month | Visible calendar month. Bind on both input and calendar for live month sync. |
| minDate / maxDate | Date | undefined | undefined | Inclusive bounds for typed values and linked calendar cells. |
| clearable | boolean | undefined | field option | Shows a clear action when the input has a value. |
| disabled | boolean | false | Disables the input and prevents opening the dropdown. |
| readonly | boolean | false | Keeps the value readable while preventing popover opening. |
| invalid | boolean | false | Reflects validation state from Signal Forms or direct binding. |
| errors / touched / touch | Signal Forms control contract | - | Integrates with Angular Signal Forms validation and touched state. |
| placeholder | string | undefined | locale layout | Native input placeholder. Defaults to the day, month and year placeholder messages in the order and separators of the locale (mm/dd/yyyy, dd.mm.yyyy). |
| id | string | undefined | field control id | Input id. Falls back to the parent kui-field control id when present. |
| kui-dropdown panelRole | 'dialog' | 'listbox' | 'grid' | null | 'listbox' | Use dialog for the calendar popover because the panel is not a listbox. |
| kui-calendar flat | boolean | false | Use flat inside the dropdown so the calendar does not draw a second frame. |
| format | string | undefined | 'locale' | Display and parse layout: d/dd, M/MM and yyyy tokens such as dd.MM.yyyy pin it. Resolves as the input, then defaults.datePicker.format, then the locale layout. |
| messages | Partial<KuiDatePickerMessages> | undefined | undefined | Per-instance text overrides (openCalendar, closeCalendar and the day, month and year placeholder tokens). They win over scoped and root messages. |
| KuiDatePickerOptions | interface | - | Shape of defaults.datePicker: clearable, format, chevronIcon and clearIcon (they take precedence over defaults.icons.pickerChevron and defaults.icons.clear). |
The input owns combobox trigger semantics and the calendar owns grid navigation.
- The input exposes
role="combobox", dialog popup state, and invalid state. - ArrowDown opens the popover; a second ArrowDown moves focus into the calendar grid.
- Escape closes the popover and returns focus to the field.
- Choosing a date in the calendar returns focus to the control, and with Angular Signal Forms the field gates the required error and
aria-invaliduntil the control is touched. - Use
kui-fieldlabels and hints so the native input has a clear accessible name and description. - Assistive-technology review is still pending for the newest date primitives.
The installed package intentionally ships single-date picking first.
- Range date picking is not implemented for
input[kuiDatePicker]. - The mobile bottom-sheet date picker variant is not implemented.
Consumer-visible changes of @kikita-labs/ui 2.0 for Date Picker.
- The class is
KuiDatePicker(it wasKuiDatePickerDirective);ng update @kikita-labs/uirenames the imports of the directive, calendar, dropdown and field. - The display and parse layout follows the locale (it was a fixed
dd.MM.yyyy); setformat="dd.MM.yyyy"ordefaults.datePicker.formatto keep the old layout. The placeholder is built from messages in the locale's order. - A sibling
kui-calendarin the same field is wired automatically (value, viewDate and the bounds); manual binding keeps working. clearableresolves as local input >defaults.datePicker>defaults.field;kuiProvideFieldOptionsis deprecated until 3.0.