The m3e-date-input component provides a segmented input for editing date and/or time values. It
supports date-only, time-only, and combined date/time entry, and integrates with m3e-form-field,
m3e-datepicker and m3e-timepicker. Each segment is independently editable for
precise, accessible, form-friendly interaction. See Form Field,
Datepicker, and
Timepicker for details.
import "@m3e/web/date-input";
This section outlines usage examples and configuration guidance for the components in this package.
The m3e-date-input is intended to be used inside m3e-form-field. The example below
shows that usage. See Form Field for details.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field"></m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
Use the value attribute to set or read the date. The beforeinput and
input fire only when all segments are fully populated. A change
fires when focus leaves the control.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field" value="2026-01-01"></m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
Different browsers interpret date strings in inconsistent ways, especially when the string resembles an ISO
date but does not include a time or timezone. To ensure predictable behavior across environments,
m3e-date-input uses a consistent, standards-aligned parsing model instead of relying on the
browser's built-in Date.parse() rules.
When m3e-date-input receives a date string, it automatically detects whether the value matches
one of the ISO-8601 formats that can be parsed safely and unambiguously:
yyyy-MM-dd — local date (no time, no timezone)yyyy-MM-ddTHH:mm:ss — local date and timeyyyy-MM-ddTHH:mm:ssZ — UTC date and timeyyyy-MM-ddTHH:mm:ss±HH:mm — date and time with an explicit timezone offset
Strings in these formats are converted into local Date objects without unexpected timezone
shifts. This prevents issues such as date-only values drifting into the previous or next day when interpreted
as UTC. If a string does not follow one of these ISO-compatible patterns, parsing may be ambiguous or
unsupported. For the most reliable results, use one of the formats above.
This component participates in form submission as a
form-associated custom element
(FACE), contributing its state to the form data. The name attribute defines the key under which
the component's value is submitted in a form. When not disabled, value is submitted as a string
value in ISO format.
The component honors the disabled state as a property-only control. When
disabled at runtime, it does not sprout a disabled attribute into the DOM.
Use the type attribute to control whether m3e-date-input edits
date (default), time, or datetime values.
When editing time-only, the existing date portion of the value is preserved. When editing
date-only, the existing time portion is preserved.
When creating a new Date in date mode, the time defaults to midnight. When creating
a new Date in time mode, the date defaults to the current day.
The following examples illustrate editing time and date/time values.
<m3e-form-field variant="outlined"> <label slot="label" for="field1">Time Field</label> <m3e-date-input id="field1" type="time" value="2026-01-01T23:30:00Z"></m3e-date-input> <span slot="hint">HH:MM</span> </m3e-form-field> <m3e-form-field variant="outlined"> <label slot="label" for="field2">Date-time Field</label> <m3e-date-input id="field2" type="datetime" value="2026-01-01T23:30:00Z"></m3e-date-input> <span slot="hint">MM/DD/YYYY HH:MM</span> </m3e-form-field>
The m3e-datepicker and m3e-timepicker integrate with
m3e-date-input using the for attribute, which binds the picker to the input by
referencing the input's ID. See Datepicker, and
Timepicker for details.
When a picker is bound to m3e-date-input, the input's own configuration takes precedence.
Properties such as min-date, max-date, blackoutDates,
min-time, max-time, blackoutTimes, time-format, and
show-seconds override the corresponding settings on the picker. This ensures the input and picker
remain consistent and enforce the same constraints.
When type="datetime" is used, a single m3e-date-input may link to both a
m3e-datepicker and a m3e-timepicker for independent date and time selection.
<m3e-form-field variant="outlined">
<label slot="label" for="field1">Date Picker</label>
<m3e-date-input id="field1"></m3e-date-input>
<m3e-icon-button aria-label="Open calendar" slot="suffix">
<m3e-icon name="calendar_today"></m3e-icon>
<m3e-datepicker-toggle for="datepicker1"></m3e-datepicker-toggle>
</m3e-icon-button>
<span slot="hint">MM/DD/YYYY</span>
</m3e-form-field>
<m3e-datepicker id="datepicker1" for="field1"></m3e-datepicker>
<m3e-form-field variant="outlined">
<label slot="label" for="field2">Time Picker</label>
<m3e-date-input id="field2" type="time"></m3e-date-input>
<m3e-icon-button aria-label="Open time picker" slot="suffix">
<m3e-icon name="schedule"></m3e-icon>
<m3e-timepicker-toggle for="timepicker1"></m3e-timepicker-toggle>
</m3e-icon-button>
<span slot="hint">HH:MM</span>
</m3e-form-field>
<m3e-timepicker id="timepicker1" for="field2"></m3e-timepicker>
<m3e-form-field variant="outlined">
<label slot="label" for="field3">Datetime Picker</label>
<m3e-date-input id="field3" type="datetime"></m3e-date-input>
<m3e-icon-button aria-label="Open calendar" slot="suffix">
<m3e-icon name="calendar_today"></m3e-icon>
<m3e-datepicker-toggle for="datepicker2"></m3e-datepicker-toggle>
</m3e-icon-button>
<m3e-icon-button aria-label="Open time picker" slot="suffix">
<m3e-icon name="schedule"></m3e-icon>
<m3e-timepicker-toggle for="timepicker2"></m3e-timepicker-toggle>
</m3e-icon-button>
<span slot="hint">MM/DD/YYYY HH:MM</span>
</m3e-form-field>
<m3e-datepicker id="datepicker2" for="field3"></m3e-datepicker>
<m3e-timepicker id="timepicker2" for="field3"></m3e-timepicker>
The time-format attribute controls the hour cycle used by the input. It accepts
"12" (default), "24", or "auto".
"12" — forces a 12-hour clock with an AM/PM meridiem."24" — forces a 24-hour clock without a meridiem."auto" — selects 12-hour or 24-hour based on the user's locale.<m3e-form-field variant="outlined"> <label slot="label" for="field1">Time Field</label> <m3e-date-input id="field1" type="time" time-format="24" value="2026-01-01T23:30:00Z"> </m3e-date-input> <span slot="hint">HH:MM</span> </m3e-form-field> <m3e-form-field variant="outlined"> <label slot="label" for="field2">Date-time Field</label> <m3e-date-input id="field2" type="datetime" time-format="24" value="2026-01-01T23:30:00Z"> </m3e-date-input> <span slot="hint">MM/DD/YYYY HH:MM</span> </m3e-form-field>
Use the show-seconds attribute to display the seconds segment when editing time.
<m3e-form-field variant="outlined"> <label slot="label" for="field1">Time Field</label> <m3e-date-input id="field1" type="time" show-seconds value="2026-01-01T23:30:00Z"> </m3e-date-input> <span slot="hint">HH:MM:SS</span> </m3e-form-field> <m3e-form-field variant="outlined"> <label slot="label" for="field2">Date-time Field</label> <m3e-date-input id="field2" type="datetime" show-seconds value="2026-01-01T23:30:00Z"> </m3e-date-input> <span slot="hint">MM/DD/YYYY HH:MM:SS</span> </m3e-form-field>
Use the disabled attribute to disable the input. When associated with a picker, the picker's
toggle button will automatically be disabled when the input is disabled to ensure the user cannot open a
picker for a value that cannot be edited.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field" value="2026-01-01" disabled></m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
Use the readonly attribute to prevent editing while still allowing focus and segment navigation.
Similar to disabled, when associated with a picker, the picker's toggle button will automatically be disabled when the input is read-only.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field" value="2026-01-01" readonly></m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
Apply the required attribute to mark the input as a mandatory field.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field" required></m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
Use the min-date and max-date attributes to mark dates before or after the
respective values as invalid.
<m3e-form-field variant="outlined"> <label slot="label" for="field">Date Field</label> <m3e-date-input id="field" value="2026-01-01" min-date="2026-01-01" max-date="2026-04-30"> </m3e-date-input> <span slot="hint">MM/DD/YYYY</span> </m3e-form-field>
In addition to min-date and max-date constraints, you can use the
blackoutDates property to specify a function used to determine whether a date invalid.
document.querySelector("#blackout-dates").blackoutDates = (date) => isWeekend(date);
Use the min-time and max-time attributes to mark times before or after the
respective values as invalid.
<m3e-form-field variant="outlined">
<label slot="label" for="field">Time Field</label>
<m3e-date-input
id="field"
type="time"
value="2026-01-01T13:15:00Z"
min-time="8:15 AM"
max-time="5:30 PM"
></m3e-date-input>
<span slot="hint">HH:MM</span>
</m3e-form-field>
In addition to min-time and max-time constraints, the
blackoutTimes property lets you provide a function that determines whether a given time is
invalid. The function receives a TimeParts object containing the hour,
minute, and secondvalues for the time being evaluated.
document.querySelector("#blackout-times").blackoutTimes = (t) => t.hour < 8 || t.hour > 18;
Use the validationMessages property to override specific validation messages. Unspecified
messages continue to use the component's defaults.
The component uses a set of validation flags to indicate which specific rule failed. Each flag corresponds to
a particular validation condition, and the component sets one or more of these flags when the current value is
invalid. These flags drive both the built-in validation messages and any custom messages you provide through
validationMessages. Only the flags that evaluate to true are considered active.
Supported flags include:
valueMissing — No value is provided when one is required.typeMismatch — The segments of the input are partially populated.rangeUnderflow — The value is earlier than min-date and/or min-time.
rangeOverflow — The value is later than max-date and/or max-time.
customError — The value falls within a disabled (blackout) range.These flags are combined to determine the final validation state and the message shown to the user.
The date and time format is automatically determined by the user's locale and cannot be customized.
Segment order follows Intl.DateTimeFormat().formatToParts(), ensuring the correct reading order
for all locales. Segment labels (mm, dd, yyyy) are provided by the
component and remain consistent across locales.
The m3e-date-input component exposes each date and time segment as an individual
spinbutton for assistive technologies. Screen readers announce the segment label (month, day,
year, hour, minute, second), the current value, and the allowed range, ensuring clear feedback as the user
edits each part of the value.
Keyboard interaction follows native segmented input patterns. Arrow keys increment or decrement the focused segment, digit keys replace the segment value, and left/right arrows move between segments. Focus remains within the component. Clearing a segment does not move focus, and additional delete/backspace presses navigate to the previous segment.
Validation states map to standard HTML constraint validation. Empty required fields report
valueMissing, and partially entered values report typeMismatch. Range constraints
use rangeUnderflow and rangeOverflow for values outside the configured
min-date, max-date, min-time, and max-time. Blackout dates
and times are reported as customError. All validity states integrate with
m3e-form-field error messaging.
The component supports accessible naming by linking to an external label through
aria-labelledby or a label element using for, ensuring the field is
correctly announced by assistive technologies.
The @m3e/web package uses
JavaScript Modules. To use it directly in a browser without a bundler, use a module script similar to the following.
<script type="module" src="/node_modules/@m3e/web/dist/date-input.js"></script>
In addition, you must use an import map to include additional dependencies.
<script type="importmap">
{
"imports": {
"tslib": "https://cdn.jsdelivr.net/npm/tslib@2.8.1/+esm",
"lit": "https://cdn.jsdelivr.net/npm/lit@3.3.0/+esm",
"lit/": "https://cdn.jsdelivr.net/npm/lit@3.3.0/",
"lit-html": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/+esm",
"lit-html/directive.js": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/directive.js",
"lit-html/directives/if-defined.js": "https://cdn.jsdelivr.net/npm/lit-html@3.3.0/directives/if-defined.js",
"@lit/reactive-element": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/+esm",
"@lit/reactive-element/": "https://cdn.jsdelivr.net/npm/@lit/reactive-element@2.0.4/",
"@m3e/web/core": "/node_modules/@m3e/web/dist/core.js"
}
}
</script>
For production builds, use the minified files to ensure optimal load performance.
The @m3e/web package includes a
Custom Elements Manifest
(custom-elements.json), which documents the properties, attributes, slots, events and CSS custom
properties of each component.
You can explore the API below, or integrate the manifest into your own tooling.