Skip to content

TimePicker ​

A time picker with dropdown hour/minute/second columns (plus an AM/PM column in 12-hour mode); ↑/↓ adjusts, Home/End jumps to bounds, Enter confirms, Esc cancels. Stepping intervals, disabled times, ranges, and direct typing are supported.

Basic Usage ​

Basic usage

Manual Input ​

Type a time (committed on blur / Enter)

Input is parsed as H:mm[:ss] (single digits tolerated, e.g. 9:5); in 12-hour mode an AM/PM word may be appended. Invalid input reverts on blur without touching the value.

Custom Format ​

format column selection

A column appears only when format contains the corresponding token.

12-Hour Mode ​

use12-hours (value stays 24-hour)

Display and columns switch to 12-hour (AM/PM words follow the locale); the fourth column toggles AM/PM. The value contract stays HH:mm:ss 24-hour.

Stepping ​

step minute interval (single number, back-compat)

step JSON triple (hour/minute/second)

step accepts {"h":2,"m":5,"s":1} for per-unit stepping; a single number remains the minute step. Values outside the step set snap to the nearest option visually without changing the value.

Disabled Times ​

disabledTime (grayed, not hidden)

disabledTime (property, (parts) => { hours?, minutes?, seconds? }) returns disabled lists per current-time context; disabled options are grayed out (clicks and keyboard skip them).

hide-disabled-options (hide disabled options instead of greying)

Used with disabledTime: hide-disabled-options removes disabled options from the columns entirely (default keeps them visible but grayed out) — in this example the current value sits in the closed hours (14–16), so those three entries are hidden from the hour column; keyboard ↑/↓ and nearest-snapping already skip disabled values at the value level, so behavior is unchanged.

Accessible Naming ​

label: trigger accessible name

label gives the trigger input an accessible name (aria-label, announced by screen readers); it falls back to placeholder when unset. An external <label for> association takes precedence (native label semantics).

Now & Presets ​

Now button (footer)

The panel footer has a built-in Now button that fills the current time and confirms.

presets quick times (property)

presets (property, an array of { label, value: 'HH:mm:ss' }) renders a button row atop the panel; clicking one applies it and closes the panel.

Timezone (timezone) ​

timezone anchor: UTC vs local

timezone accepts an IANA zone name (e.g. Asia/Tokyo) or UTC; an omitted/invalid value falls back to the host local zone. The Now button and default-time derivation read the wall clock of the configured zone; the value contract (HH:mm:ss) is unchanged. Open the left panel and click Now for UTC, the right one for the local time; the reference line below shows both zones' current time.

Time Range ​

is-range (dual column groups, auto order)

With is-range the value is a JSON array; start/end are picked independently and auto-ordered on confirm.

Form States ​

Sizes

Status & clearable

Readonly

Under readonly the panel still opens for browsing, but picking, Now, presets, clearing, and typing never commit.

Controlled Open & Events ​

oas-change / oas-confirm events

Controlled open (open + oas-open-change)

With the open attribute present the picker runs in controlled mode: gestures only emit oas-open-change, and opening/closing is decided by the host adding or removing the attribute; confirm actions (Enter, outside click, Now) emit oas-confirm alongside oas-change.

Disabled ​

Disabled

Floating Positioning (placement) ​

Explicit placement (top-end)

Same positioning contract as date-picker: fixed + collision flipping + viewport clamping; the panel width matches the trigger. 12 directions (default bottom-start).

Mobile form (bottom sheet) ​

On touch screens (coarse pointer) or narrow viewports (<768px), the panel is automatically hosted by an oas-bottom-sheet bottom sheet: rises from the viewport bottom + backdrop + drag handle swipe-down to close (backdrop click / Esc also close), with bottom safe-area inset; the hour/minute/second columns (including the dual-column range layout) scroll inside the sheet; the desktop form keeps the original floating dropdown. Inside the sheet, time option rows are lifted to a 44px touch target (--oas-touch-target-min).

required ​

required (native validation chain)

required drives the native validation chain (form-associated): when unfilled, checkValidity() returns false (valueMissing) and native form submission is blocked; it recovers to :valid once filled.

Programmatic read/write of the current value goes through the public value property: el.value reads the raw value attribute in single mode, or an array of start/end time strings in is-range mode (same shape as the oas-change detail); el.value = x writes the controlled value attribute and immediately syncs the trigger (arrays for range mode are JSON-serialized automatically, empty values remove the attribute). No events are dispatched.

API ​

oas-time-picker ​

Attributes ​

AttributeDescriptionTypeDefault
clearableClearable: shows a clear button when a value exists; emits oas-clear + oas-change (empty value)boolean—
disabledDisabledboolean—
formatDisplay format tokens; a column appears only when the corresponding token existsstringHH:mm:ss
hide-disabled-optionsHide disabled options instead of graying them out (keyboard navigation still skips them)boolean—
is-rangeTime range: value is a JSON array ["HH:mm:ss","HH:mm:ss"], auto-ordered on confirm; the typing channel is read-only in this modeboolean—
labelAccessible name (aria-label) for the trigger; an external label-for association takes precedencestring—
nameForm field name (key for native FormData submission; range mode derives name-start / name-end entries; the browser skips submission when name is absent)string—
openControlled open: present = open, removed = closed; gestures only emit oas-open-change for the host to write back; in the mobile form (touch / viewport <768px) the open panel is hosted by an oas-bottom-sheet bottom sheet (swipe-down/backdrop/Esc to close); desktop keeps the floating dropdown——
placeholderPlaceholder text——
placementPopup placement, 12 directions (default bottom-start), fixed + collision flipping + viewport clamping (same contract as date-picker)stringbottom-start
readonlyReadonly: the panel can be opened and browsed, but no interaction commitsboolean—
requiredRequired marker (drives the native valueMissing validation chain; not passed through to the inner control)boolean—
sizeSize: small / medium / large (reads the nearest config-provider injection)stringmedium
statusValidation status: success / warning / error (error also sets aria-invalid)string—
stepStepping: a JSON triple {"h":2,"m":5,"s":1} per unit; a single number remains the minute stepstring—
timezoneTimezone anchor: an IANA zone name or UTC; omitted/invalid falls back to local. The Now button and default-value derivation read this zone's wall clock; the value contract is unchangedstring—
use12-hours12-hour mode: display and columns switch to 12-hour (with an AM/PM column following the locale); the value stays 24-hourboolean—
valueCurrent value (HH:mm:ss; a JSON array when is-range)string | string[] | null—

Property (JS property; see each row for attribute reflection) ​

PropertyDescriptionTypeDefault
disabledTimeDisabled-time predicate (property function channel, (parts) => { hours?, minutes?, seconds? })| ((parts: TimeParts) => { hours?: number[]; minutes?: number[]; seconds?: number[] } | null) | null—
presetsQuick time presets (property channel, [{ label, value }])PresetItem[] | null—
valueCurrent value: a time string for single; a string array when is-rangestring | string[] | null—

Events ​

EventDescription
oas-blurThe component as a whole loses focus (internal moves do not fire)
oas-changeConfirmed value change, detail: { value } (string array for is-range)
oas-clearClear, detail: { value } is the previous value
oas-confirmEmitted on confirm actions (Enter / outside click / Now, alongside oas-change), detail: { value: detail }
oas-focusThe component as a whole gains focus
oas-open-changeOpen state change, detail: { open } (both controlled and uncontrolled)

CSS Variables ​

CSS VariableDefault
--oas-glass-blurnone
--oas-glass-ringtransparent

Keyboard: Enter / ↓ to open, ↑/↓ to adjust the current column, Home/End to jump to bounds, ←/→ to switch columns, Enter to confirm, Esc to cancel.

Released under the MIT OR Apache-2.0 License.