-
Notifications
You must be signed in to change notification settings - Fork 10
Date Time Input
- Date time input specification
Team name: Codex
Developer name: Radoslav Karaivanov
Designer name: TBD
- Radoslav Karaivanov
- Svilen Dimchevski
- Damyan Petev
- Radoslav Mirchev
| Version | Author | Date | Notes |
|---|---|---|---|
| 1 | Ivaylo Barakov | 20-Mar-2022 | First draft |
| 1.01 | Ivaylo Barakov | 22-Jul-2022 | Edit "Custom display format" section |
| 2 | Radoslav Karaivanov | 07-Aug-2026 | Aligned the specification with the current implementation: min/max, validation slots, blur-commit value semantics, removal of size/igcFocus/igcBlur; restructured to the current specification template |
The igc-date-time-input component is a single-line text editor for date and time values. The editable text is driven by a
mask derived from an input format, so the end-user always edits a predictable, positional representation of the value
(MM/dd/yyyy, HH:mm:ss, ...), while the value shown when the editor is not focused is rendered through a separate,
locale-aware display format.
The component is a form-associated custom element: it participates in native form submission and constraint validation,
exposes min/max constraints, and renders validation messages through dedicated slots.
Typical scenarios include:
- Appointment and booking forms: date and time entry with a minimum of "now" and a maximum of a booking horizon
- Filtering and reporting: from/to date editors bound to a data source query
- Audit and log views: precise timestamp entry down to the seconds part
-
Composite editors: the text-entry surface of
igc-date-pickerandigc-date-range-picker
- Masked editing: the input format is turned into a positional mask with a configurable prompt character for unfilled positions
-
Separate display format: predefined locale styles (
short,medium,long,full, and their date/time-only variants) or a custom format string - Locale awareness: the default input and display formats are resolved from the active locale and follow runtime localization changes
-
Deferred value commit: typing never mutates the public
value; the edit is committed - andigcChangeemitted - when the editor is blurred - Partial input completion: an incompletely filled mask is completed from defaults on commit, and a mask that cannot resolve to a date clears the value
-
Spinning: increment/decrement the date/time part under the caret through the keyboard, the mouse wheel, or the
stepUp/stepDownAPI, with configurable per-part deltas and optional looping -
Constraint validation:
required,minandmaxvalidators plussetCustomValidity, with per-error message slots -
Form association: submits with the form, resets to
defaultValue, and reacts to a disabled ancestor fieldset - Themeable: integrates with the theming system of the library through CSS custom properties and shadow parts
- Accessibility-first: native input semantics, label association and screen reader support
- The component must derive an editable mask from the
inputFormatproperty and default it from the active locale when the property is not set. - The component must support a configurable
promptsymbol for the unfilled positions of the mask and static literals inside the format. - The component must render the committed value through
displayFormatwhile it is not focused, and throughinputFormatwhile it is focused. - The component must support all applicable properties and API of the
igc-inputelement (label, placeholder, prefix/suffix, helper text, outlined appearance, readonly, disabled). - The public
valuemust only ever hold a committed value; intermediate editing state must not be observable through it. - The component must emit
igcInputwhile the user is editing andigcChangeonly when a committed value differs from the value the editor was focused with. - The component must complete partially entered dates on commit and clear the value when the entered text cannot resolve to a valid date.
- The component must correctly manage and report its validation state for
required,min,maxand custom validity, and render the corresponding validation message slots. - The component must participate in native form submission, reset and restore.
- The component must support spinning of the individual date/time parts through keyboard, mouse wheel and public API, honouring
spinDeltaandspinLoop. - The element must be integrated and themeable with the theming mechanism of the library.
- The element must be WAI-ARIA compliant, using the appropriate semantic elements and ARIA attributes.
- The component must support RTL layouts without additional configuration.
- The component must handle edge cases gracefully (invalid formats, out-of-range parts, incomplete input, rapid interactions).
As an end-user, I expect to be able to:
- see a date/time value formatted in a readable, locale-appropriate way when I am not editing it.
- see the positions I still have to fill clearly indicated by prompt characters when I start editing.
- see a placeholder text when the editor is empty, suggesting what I am expected to type.
- type a date and/or time value directly, with literals inserted for me as I go.
- paste, or drag-and-drop, a date from elsewhere into the editor.
- increment or decrement the date/time part my caret is in, using the keyboard or the mouse wheel.
- insert the current date and time with a single keyboard shortcut.
- have a partially typed date completed for me instead of being rejected outright.
- be told when the value I entered is required, too early, or too late.
As a developer, I expect to be able to:
- define the editable mask through an
inputFormatand have it default to the current locale when I do not. - use the input format as the placeholder when I have not set one.
- specify the prompt character used for the unfilled positions of the mask.
- set the
displayFormateither to one of the predefined styles -short,medium,long,fulland their date/time-only variants - or to a custom format string. - configure the editor as editable, readonly or disabled.
- set an initial value, and a
defaultValuethe editor resets to on form reset. - bind the value as a
Dateobject or as an ISO string. - rely on
valuereflecting only committed values, so that a two-way binding never clobbers a half-typed mask. - observe the value as it is being typed through
igcInput, and the committed value throughigcChange. - set
minandmaxvalues which control the validity of the editor. - mark the editor as
requiredand provide my own messages for each validation failure. - specify the step -
spinDelta- by which each date/time part is incremented/decremented, and whether spinning wraps around at the boundaries (spinLoop). - expect the editor to complete partially entered dates and to clear invalid input on commit.
- submit the value as part of a native
formand have it reset correctly.
A date time input is a text field that lets the user set and edit a date and time value, controlled and filtered by a mask derived from the input format. Label, placeholder, helper text, prefix/suffix content and the validation visual states follow the conventions of the other input-like components of the library.
Visual structure
- A single-line text field with an optional floating or static label, depending on the theme in use.
- Optional
prefixandsuffixcontent - typically icons or spin buttons - rendered on either side of the text. - Optional helper text below the field, replaced by the relevant validation message when the editor is invalid.
- The placeholder, when not explicitly set, is the input format itself (for example
MM/dd/yyyy), so an empty editor advertises what it expects.
Editing
-
Unfocused: the committed value is rendered through
displayFormat, so it can be considerably more verbose than what the user types (for exampleSunday, July 17, 2022). -
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; literals are skipped over automatically and unfilled positions keep showing the prompt character.
-
On blur: the edit is committed. A partially filled mask is completed from defaults (year
2000, monthJanuary, day1, time parts0), and a mask that cannot resolve to a valid date - for example02/30/2023- clears the value.
Spinning
- Keyboard: Arrow Up/Arrow Down increment/decrement the part the caret is currently in, keeping the caret in place.
- Mouse wheel: while the editor is focused, scrolling spins the part under the caret. The page does not scroll while the editor is focused.
-
Boundaries: with
spinLoopenabled - the default - a part wraps around at its boundary (minutes go from59to00); otherwise it stays clamped at the boundary.
Feedback and accessibility
- Focus indicator: the field shows the theme's focus styling; the inner native input is the focus target.
- Screen readers: the editor is a native text input with an associated label, so its value, label, description and invalid state are announced natively.
- Validation: the invalid state is applied after the editor has been interacted with, and the matching validation message slot replaces the helper text.
The igc-date-time-input component is designed for ease of integration with a declarative API that mirrors the rest of the
input-like components in the library.
The simplest editor requires no configuration at all - the input format, display format and placeholder are all derived from the active locale:
<igc-date-time-input label="Appointment"></igc-date-time-input>Add content around the text through the prefix, suffix and helper-text slots:
<igc-date-time-input label="Appointment" outlined>
<igc-icon slot="prefix" name="calendar"></igc-icon>
<span slot="helper-text">Pick a date and a time</span>
</igc-date-time-input>The inputFormat property is the mask the end-user edits. 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. |
h |
Hours in 12-hour format, single position. |
hh |
Hours in 12-hour format with an explicitly set leading zero. |
H |
Hours in 24-hour format, single position. |
HH |
Hours in 24-hour format with an explicitly set leading zero. |
m |
Minutes, single position. |
mm |
Minutes with an explicitly set leading zero. |
s |
Seconds, single position. |
ss |
Seconds with an explicitly set leading zero. |
t |
AM/PM section for 12-hour format. |
tt |
AM/PM section for 12-hour format. |
<!-- Date only -->
<igc-date-time-input input-format="dd.MM.yyyy"></igc-date-time-input>
<!-- Time only, with seconds -->
<igc-date-time-input input-format="HH:mm:ss"></igc-date-time-input>
<!-- Date and 12-hour time -->
<igc-date-time-input input-format="MM/dd/yyyy hh:mm tt"></igc-date-time-input>Setting prompt changes the character used for the positions that are not filled in yet:
<igc-date-time-input input-format="dd/MM/yyyy" prompt="*"></igc-date-time-input>Which parts the format contains also determines how min/max are compared - a time-only editor is validated on its time
portion only, and a date-only editor on its date portion only.
While the editor is not focused, the committed value is rendered through displayFormat. It accepts one of the predefined
styles below - all examples are given in the en-US locale - or a custom format string. When displayFormat is not set, it
falls back to inputFormat, and then to the locale's default date-time format.
| Option | Example |
|---|---|
short |
7/17/22, 12:00 AM |
medium |
Jul 17, 2022, 12:00:00 AM |
long |
July 17, 2022 at 12:00:00 AM GMT+3 |
full |
Sunday, July 17, 2022 at 12:00:00 AM Eastern European Summer Time |
shortDate |
7/17/22 |
mediumDate |
Jul 17, 2022 |
longDate |
July 17, 2022 |
fullDate |
Sunday, July 17, 2022 |
shortTime |
12:00 AM |
mediumTime |
12:00:00 AM |
longTime |
12:00:00 AM GMT+3 |
fullTime |
12:00:00 AM Eastern European Summer Time |
A custom display format is built from the following symbols:
| Type | Format | Description | Example |
|---|---|---|---|
| Day of month | d |
Minimum digits | 7, 17 |
dd |
Zero padded | 07, 17 | |
| Month | M |
Minimum digits | 3, 10 |
MM |
Zero padded | 03, 10 | |
MMM |
Abbreviated | Oct | |
MMMM |
Wide | October | |
MMMMM |
Narrow | O | |
| Year | y |
Numeric | 2022 |
yy |
Two digit | 22 | |
yyy |
Numeric | 2022 | |
yyyy |
Numeric | 2022 | |
| Hour 1-12 | h |
Minimum digits | 1, 12 |
hh |
Zero padded | 01, 12 | |
| Hour 0-23 | H |
Minimum digits | 1, 23 |
HH |
Zero padded | 01, 23 | |
| Minute | m |
Minimum digits | 1, 59 |
mm |
Zero padded | 01, 59 | |
| Second | s |
Minimum digits | 1, 59 |
ss |
Zero padded | 01, 59 | |
| Time period | t |
Abbreviated | AM, PM |
tt |
Abbreviated | AM, PM | |
ttt |
Short | noon | |
tttt |
Long | noon | |
ttttt |
Narrow | n |
Note: Many locales use the same time period string irrespective of the format specified. The time period also only has an effect when a 12-hour clock is used.
<igc-date-time-input
locale="fr"
input-format="dd/MM/yyyy"
display-format="fullDate"
></igc-date-time-input>The public value only ever holds a committed value. While the user is typing, the intermediate state lives in the masked
text; the parsed result reaches value - together with an igcChange event - when the edit is committed on blur.
const input = document.querySelector("igc-date-time-input")!;
// Observe the value as it is being typed - the detail is an ISO string, or
// `undefined` while the mask is still incomplete.
input.addEventListener("igcInput", ({ detail }) => {
console.log("typing:", detail);
});
// Observe committed values only. Fired on blur, and only when the committed
// value differs from the one the editor was focused with.
input.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 mask. Assigning a genuinely different value while the user is typing still wins and replaces the
mask.
The value accepts a Date, an ISO string, or null:
<igc-date-time-input value="2026-08-07T14:30:00"></igc-date-time-input>input.value = new Date(2026, 7, 7, 14, 30);
input.value = "2026-08-07T14:30:00";
input.value = null; // clears the editorCommit is lenient by design:
- A partially filled mask is completed from defaults - year
2000, monthJanuary, day1and zeroed time parts - so typing07/__/____commits as July 1st, 2000. - A mask that resolves to an invalid date -
02/30/2023,13/01/2023- commits asnull. -
clear()empties the mask and sets the value tonull.
min and max bound the valid range; required makes an empty editor invalid. Both accept a Date or an ISO string.
Validation messages are rendered through the per-error slots, replacing the helper text while the editor is invalid.
<igc-date-time-input
label="Delivery slot"
required
min="2026-08-01T09:00:00"
max="2026-08-31T18:00:00"
input-format="dd/MM/yyyy HH:mm"
>
<span slot="helper-text">Working hours in August only</span>
<span slot="value-missing">Please pick a delivery slot</span>
<span slot="range-underflow">The slot is before the delivery window</span>
<span slot="range-overflow">The slot is after the delivery window</span>
</igc-date-time-input>Custom constraints are applied through setCustomValidity, and reported through the custom-error slot:
input.addEventListener("igcChange", ({ detail }) => {
const isWeekend = detail ? [0, 6].includes(detail.getDay()) : false;
input.setCustomValidity(isWeekend ? "Weekends are not available" : "");
});spinDelta sets a per-part step; every part defaults to 1. spinLoop - enabled by default - controls whether a part wraps
around at its boundary or clamps to it.
input.spinDelta = { date: 7, minutes: 15 };
input.spinLoop = false;const input = document.querySelector("igc-date-time-input")!;
// Step the part currently under the caret, or - when not focused - the
// day part, falling back to the hours part and then to the first part
// present in the format.
input.stepUp();
input.stepDown();
// Step an explicit part, optionally with a one-off delta. The part does not
// have to be present in the input format.
input.stepUp(DatePart.Minutes, 15);
input.stepDown(DatePart.Year);
// Selection and text manipulation
input.focus();
input.select();
input.setSelectionRange(0, 2);
input.setRangeText("12", 0, 2);
// Clear the editor
input.clear();stepUp/stepDown on an empty editor initialize the value to the current date and time.
The component is a form-associated custom element, so it needs no wrapper component to participate in a form:
<form>
<igc-date-time-input name="appointment" required></igc-date-time-input>
<button type="submit">Submit</button>
<button type="reset">Reset</button>
</form>- The value is submitted under
nameas an ISO string; an empty editor is not submitted. - Enter inside the editor submits the owning form, unless the editor is invalid.
- A form reset restores
defaultValue. Setting thevalueattribute sets the default value, while assigning thevalueproperty does not. - A
disabledancestorfieldsetdisables the editor.
// Reset target, independent of the current value
input.defaultValue = new Date(2026, 0, 1);igc-date-time-input is the text-entry surface of the composite date editors of the library - igc-date-picker and
igc-date-range-picker - which forward their own label elements to the inner native input so that label association keeps
working across the shadow boundary. Applications are expected to use those components when a calendar drop-down is needed,
and igc-date-time-input directly when only a masked editor is.
The component has no static text of its own, so nothing needs to be translated. Everything locale-dependent is derived from the active locale:
-
inputFormatdefaults to the locale's date-time input pattern, so the order of the day, month and year parts follows the locale. -
placeholderdefaults to the resolved input format. -
displayFormatfalls back to the locale's default date-time format, and the predefined styles as well as the month, weekday and time period names are rendered through the locale's data.
The locale property overrides the locale for a single editor; when it is not set, the editor follows the library's global
locale. A runtime change of the global locale or of the localization resources re-resolves the default mask and re-renders the
displayed value.
<igc-date-time-input locale="ja"></igc-date-time-input>Validation messages are provided by the application through the validation message slots and are therefore localized by the application.
| Key combination | Result |
|---|---|
| ← / → | Moves the caret one position to the left/right. |
| Home / End | Moves the caret to the beginning/end of the editor. |
| Ctrl / Cmd + ← | Moves the caret to the beginning of the current date/time section, or of the previous one. |
| Ctrl / Cmd + → | Moves the caret to the end of the current date/time section, or of the next one. |
| ↑ | Increments the date/time part the caret is in. |
| ↓ | Decrements the date/time part the caret is in. |
| Ctrl / Cmd + ; | Sets the current date and time as the value of the editor. |
| Enter | Submits the owning form, if any and if the editor is valid. |
All of the above are no-ops when the editor is readonly. Modified arrow presses other than the ones listed - for example
Alt + ↑ - are ignored so that they stay available to composing components.
| Property | Attribute | Reflected | Type | Default | Description |
|---|---|---|---|---|---|
value |
value |
No | Date | string | null |
null |
The committed value of the input. Accepts a Date or an ISO string; always returns a Date or null. |
defaultValue |
- | - | Date | string | null |
null |
The value the input reverts to on form reset. Also set by the value attribute. |
inputFormat |
input-format |
No | string |
locale | The date/time pattern applied on the input. Defaults to the locale's date-time input format. |
displayFormat |
display-format |
No | string |
- | Format used to display the value when the input is not focused. Falls back to inputFormat, then to the locale. |
prompt |
prompt |
No | string |
_ |
The prompt symbol used for the unfilled positions of the mask. |
placeholder |
placeholder |
No | string |
mask | The placeholder text of the control. Defaults to the resolved input format. |
label |
label |
No | string |
- | The label for the control. |
locale |
locale |
No | string |
global | The locale used to resolve the default formats and to format the display value. Falls back to the library's global locale (en). |
min |
min |
No | Date | string | null |
null |
The minimum value required for the input to remain valid. |
max |
max |
No | Date | string | null |
null |
The maximum value required for the input to remain valid. |
spinDelta |
- | - | DatePartDeltas | undefined |
- | Per-part delta values applied on step actions. Every part defaults to 1. |
spinLoop |
spin-loop |
No | boolean |
true |
Whether spinning wraps around at the boundary of the currently spun part. |
outlined |
outlined |
Yes | boolean |
false |
Whether the control has an outlined appearance. |
readOnly |
readonly |
Yes | boolean |
false |
Makes the control a readonly field. |
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. |
spinDelta is a DatePartDeltas object with the optional numeric keys date, month, year, hours, minutes and
seconds.
| Name | Type signature | Description |
|---|---|---|
stepUp |
(datePart?: DatePart, delta?: number): void |
Increments a date/time portion. |
stepDown |
(datePart?: DatePart, delta?: number): void |
Decrements a date/time portion. |
clear |
(): void |
Clears the input element of user input. |
select |
(): void |
Selects all the text inside the input. |
focus |
(options?: FocusOptions): void |
Sets focus on the control. |
blur |
(): void |
Removes focus from the control. |
setSelectionRange |
(start: number, end: number, direction?: SelectionRangeDirection): void |
Sets the text selection range of the control. |
setRangeText |
(replacement: string, start?: number, end?: number, selectMode?: RangeTextSelectMode): void |
Replaces the selected text in the control and re-applies the mask. |
setCustomValidity |
(message: string): void |
Sets a custom validation message. As long as message is not empty, the control is 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.
| Name | Cancellable | Detail | Description |
|---|---|---|---|
igcInput |
false | string | undefined |
Fired while the user is editing - typing, spinning, or Ctrl + ;. The detail is the ISO string of the value currently in the editor, or undefined while the mask cannot resolve to a date. |
igcChange |
false | Date | null |
Fired when an edit is committed on blur and the committed value differs from the one the editor was focused with. |
invalid |
true | - | Fired when the control is found invalid during a validation cycle. |
The native focus and blur events bubble out of the component; there are no igcFocus/igcBlur counterparts.
| Name | Description |
|---|---|
prefix |
Renders content before the input. |
suffix |
Renders content after the input. |
helper-text |
Renders content below the input. |
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. |
custom-error |
Renders content when setCustomValidity(message) is set. |
invalid |
Renders content when the component is in invalid state. |
| Part | Description |
|---|---|
container |
The main wrapper that holds all main input elements. |
input |
The native input element. |
label |
The native label element. |
prefix |
The prefix wrapper. |
suffix |
The suffix wrapper. |
helper-text |
The helper text wrapper. |
- The component does not expose a
typeattribute, since the underlying element is always an input of type text. - Undo/redo of the masked text is not supported.
- The
valueis a localDate; time zones are not modelled. A display format including a time zone renders the runtime's time zone. - The input format is positional. Variable-width tokens that are valid in a display format -
MMM,MMMM,ttt- are not supported as input format tokens. - Any year token other than
yyis normalized toyyyyfor editing purposes. - Two-digit years below
50resolve to the 2000s;50and above resolve to the 1900s. - A single-character token -
d,M,h- yields a single editable position; use the doubled token when a zero-padded, two-position section is required. - The
maskandpromptmembers are inherited from the shared masked-editor behavior. Onlypromptis supported here -inputFormatis the supported way of setting the pattern. - Only one date/time value is edited per component; ranges are covered by
igc-date-range-picker.
-
Default rendering
- The component renders a native text input with the default mask, prompt and placeholder for the active locale
-
valueisnulland no validation styling is applied - Label, helper text, prefix and suffix content render in their respective slots
-
Initial value
- Setting the
valueattribute to an ISO string initializes the value and the displayed text - Setting the
valueproperty to aDateinitializes the value and the displayed text - Setting a value with a time portion only is handled correctly
- An invalid initial value resolves to
null
- Setting the
-
Format resolution
-
inputFormatdefaults to the locale's date-time format when not set - Changing
localeupdates the resolved input format, with and without a value present - A runtime localization resource change updates the resolved input format, with and without a value present
- Setting
inputFormatexplicitly overrides the locale default - The placeholder follows the resolved input format while it has not been explicitly set
-
-
Mask editing
- The mask exposes one editable position per format character and skips literals while typing
- Unfilled positions render the
promptcharacter, and changingpromptre-renders them - The mask is re-applied according to
inputFormaton focus when a value is already set - Out-of-range sections keep the mask editable and resolve on commit
- Formats containing seconds and AM/PM sections are handled correctly
-
Predefined and custom formats
- The value is rendered through
displayFormatwhile the input is not focused - Switching between the predefined date-time, date-only and time-only styles renders the expected text
- A custom display format string renders the expected text
-
displayFormatfalls back toinputFormat, and then to the locale default, when not set - The text flips to the input format on focus and back to the display format on blur
- The value is rendered through
-
Uncommitted edits
- Typing does not mutate
value, neither for a partial nor for a complete mask -
igcInputexposes the typed value as an ISO string whilevaluestays put - Re-applying an equal value while typing does not reset the mask
- A genuinely different value assigned while typing replaces the mask
- Typing does not mutate
-
Commit on blur
- A complete mask commits its value on blur and emits a single
igcChangecarrying it - An incomplete mask is completed from defaults on commit and emits
igcChange - A mask that resolves to an invalid date commits
null - No
igcChangeis emitted when the committed value equals the value the input was focused with - No
igcChangeis emitted when the control isreadonly - A value assigned programmatically while focused is treated as a committed change
- A complete mask commits its value on blur and emits a single
-
Clearing
-
clear()empties the mask and setsvaluetonull - Assigning
nullclears the value and the displayed text
-
-
stepUp/stepDown
- Step the part under the caret when focused, and the default part when not
- Initialize a new date when the value is empty
- Accept an explicit
DatePart, including one not present in the input format - Accept a one-off
deltaargument - Respect
spinDeltaper part - Respect
spinLoopat the boundaries of each part - Do not move the caret away from the part being spun
-
Mouse wheel
- Scrolling spins the part under the caret while the input is focused
- Scrolling is a no-op when the input is not focused
- Scrolling is a no-op when the input is
readonly
-
Caret movement
- Arrow left/right move the caret one position
-
Ctrl/Cmd+ arrow left/right jump to the beginning/end of the adjacent date/time section - Clicking positions the caret inside the corresponding section
-
Keyboard spinning and shortcuts
- Arrow up/down step the part under the caret and emit
igcInput - Arrow up/down are a no-op when the input is
readonly -
Alt+ arrow up/down are a no-op -
Ctrl/Cmd+;sets the current date and time as the value
- Arrow up/down step the part under the caret and emit
-
Text transfer
-
setRangeText()replaces the selected text and re-applies the mask - Dragging text over an unfocused input flips it to the editable mask
- Dragging away from an unfocused input restores the display value
- Dropping text onto the input applies and commits it without a blur
-
-
Constraints
-
requiredinvalidates an empty editor and validates a filled one -
mininvalidates values before it, for bothDateand ISO string bindings -
maxinvalidates values after it, for bothDateand ISO string bindings - A time-only format is validated on the time portion, and a date-only format on the date portion
-
setCustomValidity()invalidates the editor while the message is not empty -
checkValidity()andreportValidity()report the expected result and emitinvalidwhen appropriate - Validation styling is applied only after the editor has been interacted with
-
-
Validation message slots
-
value-missing,range-underflow,range-overflowandcustom-errorcontent renders for the corresponding failure -
invalidslot content renders while the editor is invalid - Validation messages replace the helper text and are cleared when the editor becomes valid
- Validation messages persist after a failed form submission
-
-
Submission and reset
- The element is form associated
- An empty editor is not submitted
- A filled editor is submitted under its
name -
Entersubmits the owning form, and does not submit while the editor is invalid - A form reset restores
defaultValue - Setting the
valueattribute updates the default value used on reset -
defaultValueparticipates inrequired,minandmaxvalidation - The editor reflects a disabled ancestor
fieldset
-
Locale-driven behavior
- Month, weekday and time period names follow the
locale - Changing
localere-renders the displayed value - A runtime resource change re-renders both the mask and the displayed value
- Month, weekday and time period names follow the
-
Semantics
- The inner element is a native text input reachable through
Tab -
labelis associated with the inner input, and labels forwarded by a composite host take precedence - Helper text is referenced through
aria-describedby - The invalid state is exposed to assistive technology
-
disabledandreadonlyare propagated to the inner input
- The inner element is a native text input reachable through
-
Right-to-Left
- The editor renders and edits correctly in an RTL context
- Caret navigation and section jumps behave correctly in RTL
-
Invalid configuration and rapid interaction
- An input format with no supported format characters degrades gracefully
- Invalid
min/maxvalues are ignored rather than throwing -
mingreater thanmaxbehaves predictably - Rapid typing, spinning and focus changes do not desynchronize the mask from the value
- Leap years and month-length changes are handled when spinning the year and month parts
- Spinning the AM/PM part does not roll the date over
The editable surface is a native <input type="text">, so the majority of the semantics come for free:
- the inner input is labelled by the component's
label, or by the label elements forwarded by a composite host, through aria-labelledby. - when helper text or a validation message is rendered, the inner input references it through aria-describedby.
- the
disabledandreadonlystates are set on the inner input, so they are exposed natively. - the invalid state is exposed through the element's
ElementInternalsvalidity, so assistive technology is notified of a failed constraint. - the component sets
delegatesFocus, so focusing the host focuses the inner input.
Already covered by the relevant section of the specification.
The date time input should work in a Right-to-Left context without additional setup or configuration.