Skip to content

DatePicker

A date field built on the native <input type="date">, with the root field composition around it.

Usage

<input is="root-date-picker" data-label="Start date" value="2026-08-20" />

The picker is the platform's own: the user agent draws it, localizes it, and keeps parsing, stepping and constraint validation. The component sets type="date" itself, so the tag is all the author has to get right, and adds the shared field composition - the [field-wrapper] span that carries the box, the <label>, the required marker and the hint.

<label>
  <span data-part="label">Start date</span>
  <span field-wrapper>
    <input is="root-date-picker" type="date" />
  </span>
  <span data-part="hint" aria-live="polite">…</span>
</label>

Sizes

data-size takes small and large; the default is the medium step and has no value to write. The wrapper heights and the label scaling are Input's - the field composition is the same decorator.

<input is="root-date-picker" data-size="large" data-label="Large" value="2026-08-20" />
<input is="root-date-picker" data-label="Medium" value="2026-08-20" />
<input is="root-date-picker" data-size="small" data-label="Small" value="2026-08-20" />

Range and stepping

min and max take a date (2026-01-01), step a number of days. Both are the platform's, and both feed the browser's own validation message - which is what the hint falls back to when no data-error is authored.

<input is="root-date-picker" data-label="Start date" min="2026-01-01" max="2026-12-31" required />

Hint and error

data-hint holds the description and data-error the error message: both are authored once, and data-invalid decides which one shows. One node carries both, wired to the control through aria-describedby, and an invalid control also gets aria-invalid. With no data-error the browser's own validationMessage stands in - already localized.

<input
  is="root-date-picker"
  required
  data-label="Start date"
  data-hint="Bookings open three months ahead"
  data-error="Pick a date inside the booking window"
/>

Required

required is the native attribute; the asterisk beside the label is drawn from it and hidden from assistive tech, which reads the control's own required instead.

<input is="root-date-picker" required data-label="Start date" />

States

Hover moves the border one step deeper and focus takes the Default step, exactly as on Input - the border moving is the indicator, so focus draws no ring. disabled repaints the box and takes the not-allowed cursor; readonly carries no styling of its own, the value being selectable and the field still focusable.

<input is="root-date-picker" data-label="Tab to me" />
<input is="root-date-picker" value="2026-08-20" disabled data-label="Disabled" />
<input is="root-date-picker" value="2026-08-27" readonly data-label="Read-only" />

Inline layout

inline on the <label> lays the label text and the field on one row instead of stacking them. It has to sit on the label, which means authoring the label yourself - the generated one takes no attributes from the control.

<label inline>
  <span data-part="label">Start date</span>
  <span field-wrapper>
    <input is="root-date-picker" type="date" data-size="small" value="2026-08-20" />
  </span>
</label>

Attributes

Attribute Type Default Description
type 'date' 'date' Forced by the component
value string - Platform format, e.g. 2026-08-20
min / max string - Bounds, in the same format as value
step number - Platform stepping
data-label string - Label text; the component builds the <label>
required boolean false Marks the field required and draws the asterisk
data-hint string - Description shown under the field
data-error string - Error message; falls back to validationMessage
data-invalid 'true' - Shows the error instead of the description
disabled boolean false Disables the field
readonly boolean false Read-only state

Parts

Part Description
[field-wrapper] The field box around the control
[data-part="label"] The label text, holding the required marker
[data-part="required"] The decorative asterisk
[data-part="hint"] The description / error node

Events

Namespaced as <component>.<event>, bubbling and cancelable; detail also carries the originating DOM event as originalEvent.

Event Detail Description
root-date-picker.input { value } Fired on input
root-date-picker.change { value } Fired on change
root-date-picker.focus { value } Fired on focus
root-date-picker.blur { value } Fired on blur
root-date-picker.invalid { value } Fired when the control fails constraint validation
root-date-picker.data-label.change { value, oldValue } Fired when the label text changes

Extends

HTMLInputElement - use with <input is="root-date-picker">.