Date Input
import { DateInput } from '@absoluteui/components/date-input';import '@absoluteui/components/date-input/style.css';Using Angular? See Date Input for Angular.
What it does
Section titled “What it does”Keyboard-first date or date-time entry using numeric segments ordered for the locale. Values are explicit types:
- date granularity produces a
PlainDate; - minute granularity produces an
Instant, resolved in the configured timezone with a documented DST policy.
When to use
Section titled “When to use”- Entering known dates such as birth dates or due dates.
- Entering an exact moment (meeting time) in a specific timezone.
When not to use
Section titled “When not to use”- Browsing dates visually: use Date Picker or DateTime Picker. Choosing ranges: use Date Range Picker.
- Relative or fuzzy dates (‘next week’).
Examples
Section titled “Examples”Date-only value with bounds
Section titled “Date-only value with bounds”import { plainDate, plainDateToString, type PlainDate } from '@absoluteui/core';import { DateInput, type DateInputChangeDetail } from '@absoluteui/components/date-input';
const host = document.createElement('div');document.body.append(host);DateInput.create(host, { label: 'Due date', name: 'due', min: plainDate(2026, 1, 1), required: true });host.addEventListener('aui-change', (event) => { const { value } = (event as CustomEvent<DateInputChangeDetail>).detail; if (value?.kind === 'PlainDate') { const due: PlainDate = value; document.title = plainDateToString(due); }});Exact meeting time in a configured timezone
Section titled “Exact meeting time in a configured timezone”import { configureAbsoluteUI, instantToString } from '@absoluteui/core';import { DateInput, type DateInputChangeDetail } from '@absoluteui/components/date-input';
configureAbsoluteUI({ common: { timezone: 'Asia/Kolkata' }, components: { dateInput: { disambiguation: 'reject' } } });const host = document.createElement('div');document.body.append(host);DateInput.create(host, { label: 'Meeting time', granularity: 'minute' });host.addEventListener('aui-change', (event) => { const { value } = (event as CustomEvent<DateInputChangeDetail>).detail; if (value?.kind === 'Instant') document.title = instantToString(value);});import { configureAbsoluteUI } from '@absoluteui/core';import { DateInput } from '@absoluteui/components/date-input';import '@absoluteui/components/date-input/style.css';
configureAbsoluteUI({ timezone: 'America/New_York' });const host = document.querySelector<HTMLElement>('#meeting');if (host) DateInput.create(host, { label: 'Meeting time', granularity: 'minute', name: 'meeting' });More usage
Section titled “More usage”import { plainDate } from '@absoluteui/core';import { DateInput } from '@absoluteui/components/date-input';
const host = document.createElement('div');document.body.append(host);DateInput.create(host, { label: 'Due date', name: 'due', min: plainDate(2026, 1, 1) });Anatomy
Section titled “Anatomy”<div class="aui-date-input"> (consumer host) <div class="aui-date-input__label" id> <div class="aui-date-input__group" role="group" aria-labelledby aria-describedby> <div class="aui-date-input__fields"> <input class="aui-date-input__segment aui-date-input__segment--month" aria-label="Month"> <span class="aui-date-input__separator" aria-hidden="true">/</span> ... </div> </div> <div class="aui-date-input__description"> <div class="aui-date-input__hint"> <div class="aui-date-input__error"> <input type="hidden" name></div>API reference
Section titled “API reference”Factory
Section titled “Factory”DateInput.create(host: HTMLElement, options: DateInputOptions): DateInputGlobal configuration key: dateInput (see Configuration).
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
label |
string |
Group label and accessible name. Required. | |
value |
PlainDate | Instant | null |
null |
PlainDate for date granularity; Instant for minute granularity. |
min |
PlainDate | Instant | null |
Inclusive lower bound. | |
max |
PlainDate | Instant | null |
Inclusive upper bound. | |
name |
string |
Form field name for the ISO 8601 hidden input. | |
description |
string |
Help text referenced by aria-describedby. | |
required |
boolean |
false |
Empty value is invalid (value-missing). |
disabled |
boolean |
false |
Disables all segments. |
readOnly |
boolean |
false |
Prevents editing. |
trailing |
HTMLElement |
Advanced: element appended inside the group boundary after the segments (used by Date Picker for its calendar button). Focus moving into it does not mark the field touched. | |
formControl |
boolean |
true |
Advanced, read at creation: false skips registration with Form, for composite controls such as Date Picker that register themselves. Set at creation only. |
granularity |
'date' | 'minute' |
"date" |
Value type and segments. Globally configurable. Set at creation only. |
hourCycle |
'auto' | 'h12' | 'h23' |
"auto" |
12/24-hour clock; auto follows the locale. Globally configurable. |
locale |
string |
"en-US" |
Segment order, labels, messages, formatting. Globally configurable. Inherited from common configuration. |
timezone |
string (IANA) |
"UTC" |
Zone for minute granularity. Globally configurable. Inherited from common configuration. |
disambiguation |
'compatible' | 'earlier' | 'later' | 'reject' |
"compatible" |
DST policy for nonexistent/ambiguous local times. Globally configurable. Inherited from common configuration. |
direction |
'ltr' | 'rtl' |
"ltr" |
Arrow-key segment navigation direction. Globally configurable. Inherited from common configuration. |
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
host |
HTMLElement |
Consumer-provided host (children are owned by the component). |
group |
HTMLDivElement |
role=group container of the segments. |
value |
PlainDate | Instant | null |
Current valid value, or null when empty/invalid. |
validity |
{ valid: boolean; error: DateInputError | null; localTimeStatus: 'exact' | 'ambiguous' | 'nonexistent' | null } |
Validation state. |
name |
string | null |
Form field name. |
label |
string |
Label text. |
disabled |
boolean |
Disabled state. |
dirty |
boolean |
Value differs from the initial value. |
touched |
boolean |
Focus has left the control at least once. |
localValue |
PlainDateTime | null |
Minute granularity: the complete wall-clock date and time in the segments, even when the zone rejects it; else null. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
setValue(value: PlainDate | Instant | null): void |
Programmatic value (no aui-change). |
setLocalValue(value: PlainDateTime | null): void |
Minute granularity, for composite controls: write a wall-clock date-time resolved as if typed (timezone, disambiguation, DST hint or error). No aui-change. |
update(options: Partial<DateInputOptions>): void |
Merge and apply options; init-only options throw. |
reportValidity(): boolean |
Show messages immediately; returns validity. |
destroy(): void |
Remove listeners, subscriptions, and rendered children. |
setCustomError(message: string | null): void |
External error (server, cross-field rule); cleared when the user changes the value. |
focus(): void |
Focus the control. |
reset(): void |
Restore the initial value and clear touched/submitted state (no aui-change). |
getFormValue(): string | null |
ISO 8601 value (YYYY-MM-DD or instant with Z), or null when empty or invalid. |
Events
Section titled “Events”| Event | Detail | Bubbles | Cancelable | Description |
|---|---|---|---|---|
aui-change |
{ value: PlainDate | Instant | null; validity: DateInputValidity } |
Yes | No | User edit changed the value or validity. |
CSS classes
Section titled “CSS classes”All rules live in the aui.components cascade layer, so application styles override them without specificity battles.
| Class | Purpose |
|---|---|
aui-date-input |
Host. |
aui-date-input--invalid | --disabled |
State modifiers on the host. |
aui-date-input__label |
Group label. |
aui-date-input__group |
role=group control surface. |
aui-date-input__segment |
Segment input; –year/–month/–day/–hour/–minute/–dayPeriod modifiers. |
aui-date-input__separator |
Locale separator (aria-hidden). |
aui-date-input__description | __hint | __error |
Help, timezone/DST hint, and error text. |
Design tokens
Section titled “Design tokens”Tokens this stylesheet reads (verified in CI). Override them in a theme or with the Theme Designer.
--aui-border-width | --aui-color-border | --aui-color-border-strong | --aui-color-disabled-bg | --aui-color-error-fg | --aui-color-focus-ring | --aui-color-selected | --aui-color-selected-text | --aui-color-surface | --aui-color-text | --aui-color-text-disabled | --aui-color-text-muted | --aui-control-height-md | --aui-control-padding-x | --aui-duration-fast | --aui-easing-standard | --aui-focus-ring-width | --aui-font-family-sans | --aui-font-size-md | --aui-font-size-sm | --aui-font-weight-medium | --aui-icon-size-sm | --aui-line-height-normal | --aui-line-height-tight | --aui-radius-md | --aui-radius-sm | --aui-space-1
TypeScript definitions
Section titled “TypeScript definitions”type DateInputValue = PlainDate | Instant;type DateInputError = 'incomplete' | 'invalid-date' | 'value-missing' | 'range-underflow' | 'range-overflow' | 'nonexistent-time' | 'ambiguous-time';interface DateInputValidity { readonly valid: boolean; readonly error: DateInputError | null; readonly localTimeStatus: 'exact' | 'ambiguous' | 'nonexistent' | null }interface DateInputChangeDetail { value: DateInputValue | null; validity: DateInputValidity }Accessibility
Section titled “Accessibility”Pattern: Labelled group of labelled text inputs (segmented date field). No APG pattern exists for segmented date fields; native text inputs are used for maximum assistive technology compatibility.
Keyboard
Section titled “Keyboard”| Key | Context | Action |
|---|---|---|
| Digits | Segment focused | Enter value; auto-advance when complete. |
| ArrowUp / ArrowDown | Segment focused | Increment/decrement with wrap (year clamps); toggles AM/PM. |
| ArrowLeft / ArrowRight | Caret at segment edge | Move to previous/next segment (mirrored in RTL). |
| Backspace | Empty segment | Move to previous segment. |
| / - . : , Space | Numeric segment | Pad the current value and advance. |
| A / P | AM/PM segment | Set AM or PM. |
| Tab / Shift+Tab | Any | Move between segments and out of the group. |
| Element | Role |
|---|---|
| group container | group |
| each segment | textbox (native input, inputmode=numeric) |
| separators | none (aria-hidden=true) |
ARIA attributes
Section titled “ARIA attributes”| Attribute | Element | Value |
|---|---|---|
aria-labelledby |
group | id of the visible label |
aria-label |
segment | Localized segment name (Year, Month, Day, Hour, Minute, AM/PM) |
aria-describedby |
group | description, timezone/DST hint, and error ids as applicable |
aria-invalid |
segment | true while an error message is shown |
Each segment is a tab stop; focusing selects its content. Focused segment is highlighted with selected colors and a focus outline.
WCAG 2.2 success criteria addressed
Section titled “WCAG 2.2 success criteria addressed”| Criterion | Level | Note |
|---|---|---|
| 1.3.1 Info and Relationships | A | |
| 1.3.5 Identify Input Purpose | AA | |
| 2.1.1 Keyboard | A | |
| 2.4.7 Focus Visible | AA | |
| 3.3.1 Error Identification | A | |
| 3.3.2 Labels or Instructions | A | |
| 3.3.3 Error Suggestion | AA | |
| 4.1.2 Name, Role, Value | A |
Automated test results: Accessibility and compliance.
Notes and known caveats
Section titled “Notes and known caveats”- Error messages identify the problem and, for DST cases, the timezone.
- Adjustments caused by daylight-saving rules are disclosed in the hint rather than applied silently.
- Each segment is a separate tab stop; some users may prefer a single field. Manual screen-reader and user testing is pending.
Behavior
Section titled “Behavior”States
Section titled “States”empty, incomplete, valid, invalid-date, value-missing, range-underflow, range-overflow, nonexistent-time, ambiguous-time, disabled, read-only.
State transitions
Section titled “State transitions”| From | Trigger | To |
|---|---|---|
| empty | First digit | incomplete (message shown only after blur or reportValidity()) |
| incomplete | All segments filled | valid, or invalid-date, range-underflow, range-overflow, nonexistent-time, ambiguous-time |
| any | Segment cleared | incomplete, or empty (value-missing if required) |
Accessibility notes
Section titled “Accessibility notes”- Error messages name the problem; DST messages also name the timezone.
- Daylight-saving adjustments are disclosed in the hint, never applied silently.
- Each segment is a tab stop.
- Verified with axe (WCAG 2.2 AA) in 3 themes. Manual screen-reader and user testing is pending.
Responsive behavior
Section titled “Responsive behavior”Segments wrap inside the group in narrow containers. The group fits its content, up to 100% of the container width.
Right-to-left
Section titled “Right-to-left”Segment order comes from the locale’s Intl pattern. Digits stay LTR and isolated. Arrow-key segment navigation mirrors in RTL.
Theming
Section titled “Theming”Token-driven. In forced-colors mode, the focused segment uses Highlight/HighlightText.
Global configuration
Section titled “Global configuration”configureAbsoluteUI({ common: { timezone: 'Europe/London' }, components: { dateInput: { hourCycle: 'h23' } } });Component configuration
Section titled “Component configuration”Instance options override global and theme defaults. granularity is init-only; all other options are dynamic and rebuild the segments while preserving the entered values.
Timezones
Section titled “Timezones”- Date granularity: timezone-independent
PlainDate. The calendar date never shifts. - Minute granularity: wall-clock input is resolved in
timezone. The default is UTC; the host timezone is never used.
DST handling in minute granularity:
| Case | compatible (default) |
earlier |
later |
reject |
|---|---|---|---|---|
| Nonexistent (clock springs forward) | shift forward + hint | shift backward + hint | shift forward + hint | error nonexistent-time |
| Ambiguous (clock falls back) | earlier occurrence + hint | earlier + hint | later + hint | error ambiguous-time |
The hint always shows the zone name and offset, for example “Time zone: India Standard Time (GMT+05:30)”.
Security
Section titled “Security”All text uses textContent; no HTML parsing. CSP-safe.
Data handling
Section titled “Data handling”No persistence, network access, or telemetry. When name is set, the hidden input carries ISO 8601: YYYY-MM-DD, or a UTC instant such as 2026-03-08T07:30:00.000Z.
Performance
Section titled “Performance”Each edit recomputes only this instance: one parse, and up to 3 timezone offset lookups with cached Intl.DateTimeFormat instances. Budget: under 5 ms average per DateInput.create across 100 instances in headless Chromium.
Supported data scale
Section titled “Supported data scale”100 instances per page in the performance test.
Edge cases
Section titled “Edge cases”- February 30 reports
invalid-dateimmediately. - 02:30 on 2026-03-08 in
America/New_Yorkbecomes 03:30 EDT with a hint undercompatible, or an error underreject. - 01:30 on 2026-11-01 in
America/New_Yorkresolves to the EDT occurrence (05:30Z) undercompatible. - Instants are displayed in the configured zone; for example 2026-12-31T20:00Z shows as 2027-01-01 01:30 in
Asia/Kolkata. - Years 1 to 99 are supported without the
Date.UTC1900 mapping bug.
Errors
Section titled “Errors”| Code | Category | Cause |
|---|---|---|
DATE_INPUT_LABEL |
configuration | Missing label. |
DATE_INPUT_TRAILING |
configuration | trailing is not an element. |
DATE_INPUT_VALUE_KIND |
configuration | Value, min, or max type does not match the granularity. |
CFG_INIT_ONLY |
configuration | Changing granularity after creation. |
| Validation errors | validation (validity.error) |
incomplete, invalid-date, value-missing, range-underflow, range-overflow, nonexistent-time, ambiguous-time. |
Known limitations
Section titled “Known limitations”- No calendar popup; use Date Picker.
- Gregorian calendar only; years 1 to 9999. Minute precision only.
- Timezone rules come from the browser’s ICU data.
- Manual screen-reader and user testing is pending.
Unsupported scenarios
Section titled “Unsupported scenarios”- Free-form localized text parsing.
- Changing
granularityafter creation.