Date Picker composes the directive, Field, Dropdown, and Calendar public APIs.

date-picker.ts
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.

Type the date in your locale's layout or choose from 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.

meeting.html
<!-- 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.

Follows the locale of the nearest i18n level.

format pins dd.MM.yyyy whatever the locale is.

<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/2026 in en-US, 03.10.2026 in ru-RU and 2026/10/03 in ja-JP. The placeholder is built from the dayPlaceholder, monthPlaceholder and yearPlaceholder messages in the same order and separators.
  • format takes d/dd, M/MM and yyyy tokens such as dd.MM.yyyy and resolves as the input, then defaults.datePicker.format, then the locale.
  • Parsing reads three digit groups in the layout's order, so 3.1.2026 is accepted where 03.01.2026 is shown. Surrounding whitespace is trimmed and four-digit years from 0000 through 9999 are 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-invalid and data-kui-invalid without replacing the last parsed value.
  • A parseable date outside the bounds updates value and viewDate to 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.
  • readonly shows the value but never opens the popover; clearable defaults 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 maxHeight as 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) that panelWidth="auto" keeps.
  • Use flat on 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 */
        },
      },
    }),
  ],
};
NameTypeDefaultDescription
clearableboolean — When true, field controls with clear affordances show a clear button by default.
chevronIconKuiIconGlyph — Icon of the options toggle. Takes precedence over defaults.icons.pickerChevron. See Structural Icons.
clearIconKuiIconGlyph — 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.

NameTypeDefaultDescription
--kui-date-picker-chevron-color-expandedCSS custom property--kui-color-primary-textChevron color, expanded
NameTypeDefaultDescription
--kui-date-picker-control-overlay-padding-inlineCSS custom property--kui-space-3Control overlay padding, inline
--kui-date-picker-padding-inline-startCSS custom property34pxInput start padding that clears the calendar icon
--kui-date-picker-padding-inline-endCSS custom property34pxInput end padding that clears the chevron
--kui-date-picker-padding-inline-end-clearableCSS custom property56pxInput 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.

NameTypeDefaultDescription
openCalendarstring — Name of the button that opens the calendar. Default Open calendar.
closeCalendarstring — Name of the button that closes the calendar. Default Close calendar.
dayPlaceholderstring — Placeholder token for the day field. Default dd.
monthPlaceholderstring — Placeholder token for the month field. Default mm.
yearPlaceholderstring — 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.

NameTypeDefaultDescription
input[kuiDatePicker]Directive-Turns a native text input into a masked date picker trigger.
[(value)]Date | nullnullSelected date. Bind the same signal to the paired calendar.
[(viewDate)]Datecurrent monthVisible calendar month. Bind on both input and calendar for live month sync.
minDate / maxDateDate | undefinedundefinedInclusive bounds for typed values and linked calendar cells.
clearableboolean | undefinedfield optionShows a clear action when the input has a value.
disabledbooleanfalseDisables the input and prevents opening the dropdown.
readonlybooleanfalseKeeps the value readable while preventing popover opening.
invalidbooleanfalseReflects validation state from Signal Forms or direct binding.
errors / touched / touchSignal Forms control contract-Integrates with Angular Signal Forms validation and touched state.
placeholderstring | undefinedlocale layoutNative 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).
idstring | undefinedfield control idInput 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 flatbooleanfalseUse flat inside the dropdown so the calendar does not draw a second frame.
formatstring | 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.
messagesPartial<KuiDatePickerMessages> | undefinedundefinedPer-instance text overrides (openCalendar, closeCalendar and the day, month and year placeholder tokens). They win over scoped and root messages.
KuiDatePickerOptionsinterface-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-invalid until the control is touched.
  • Use kui-field labels 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 was KuiDatePickerDirective); ng update @kikita-labs/ui renames the imports of the directive, calendar, dropdown and field.
  • The display and parse layout follows the locale (it was a fixed dd.MM.yyyy); set format="dd.MM.yyyy" or defaults.datePicker.format to keep the old layout. The placeholder is built from messages in the locale's order.
  • A sibling kui-calendar in the same field is wired automatically (value, viewDate and the bounds); manual binding keeps working.
  • clearable resolves as local input > defaults.datePicker > defaults.field; kuiProvideFieldOptions is deprecated until 3.0.