Date Input

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";
Usage

This section outlines usage examples and configuration guidance for the components in this package.

Basic usage

The m3e-date-input is intended to be used inside m3e-form-field. The example below shows that usage. See Form Field for details.

MM/DD/YYYY
<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>
Value binding

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.

MM/DD/YYYY
<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>
Date string handling

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:

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.

Form Associated

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.

Editing modes

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.

HH:MM MM/DD/YYYY HH:MM
<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>
Date and time pickers

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.

MM/DD/YYYY HH:MM MM/DD/YYYY HH:MM
<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>
Hour format

The time-format attribute controls the hour cycle used by the input. It accepts "12" (default), "24", or "auto".

HH:MM MM/DD/YYYY HH:MM
<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>
Seconds

Use the show-seconds attribute to display the seconds segment when editing time.

HH:MM:SS MM/DD/YYYY HH:MM:SS
<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>
Disabling

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.

MM/DD/YYYY
<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>
Readonly

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.

MM/DD/YYYY
<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>
Required

Apply the required attribute to mark the input as a mandatory field.

MM/DD/YYYY
<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>
Min and max dates

Use the min-date and max-date attributes to mark dates before or after the respective values as invalid.

MM/DD/YYYY
<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>
Blackout dates

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.

MM/DD/YYYY
document.querySelector("#blackout-dates").blackoutDates = (date) => isWeekend(date);
Min and max times

Use the min-time and max-time attributes to mark times before or after the respective values as invalid.

HH:MM
<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>
Blackout times

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.

HH:MM
document.querySelector("#blackout-times").blackoutTimes = (t) => t.hour < 8 || t.hour > 18;
Validation messages

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:

These flags are combined to determine the final validation state and the message shown to the user.

Internationalization

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.

Accessibility

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.

Native module support

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.

API

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.

m3e-date-input
On this page Date Input