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">.