Skip to content

TimePicker

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

Usage

<input is="root-time-picker" data-label="Start time" value="09:30" />

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="time" 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 time</span>
  <span field-wrapper>
    <input is="root-time-picker" type="time" />
  </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-time-picker" data-size="large" data-label="Large" value="09:30" />
<input is="root-time-picker" data-label="Medium" value="09:30" />
<input is="root-time-picker" data-size="small" data-label="Small" value="09:30" />

Range and stepping

min and max take a time (09:00), step a number of seconds - step="900" gives quarter hours. 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-time-picker" data-label="Start time" min="09:00" max="18:00" 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-time-picker"
  required
  data-label="Start time"
  data-hint="Opening hours are 09:00 to 18:00"
  data-error="Pick a time inside opening hours"
/>

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-time-picker" required data-label="Opens at" />

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-time-picker" data-label="Tab to me" />
<input is="root-time-picker" value="09:30" disabled data-label="Disabled" />
<input is="root-time-picker" value="18:00" 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">Opens at</span>
  <span field-wrapper>
    <input is="root-time-picker" type="time" data-size="small" value="09:30" />
  </span>
</label>

Attributes

Attribute Type Default Description
type 'time' 'time' Forced by the component
value string - Platform format, e.g. 09:30
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-time-picker.input { value } Fired on input
root-time-picker.change { value } Fired on change
root-time-picker.focus { value } Fired on focus
root-time-picker.blur { value } Fired on blur
root-time-picker.invalid { value } Fired when the control fails constraint validation
root-time-picker.data-label.change { value, oldValue } Fired when the label text changes

Extends

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