Component
Vue Time Picker Component
<DomTimeSelector>A typed time field with a popover list of selectable times. Stores HH:mm by default and can display 12-hour or 24-hour labels.
Playground
Try every prop live
Time selector playground
The input stores HH:mm by default. Use timeFormat for 12-hour labels, minuteStep for generated options, and min/max to constrain selection.
Type a time or choose one from the generated list.
Properties
Control props
Selected time as HH:mm, or HH:mm:ss when showSeconds is enabled.
How times are displayed in the input and option list.
Minute interval used to generate selectable options.
Minimum selectable time as HH:mm or HH:mm:ss.
Maximum selectable time as HH:mm or HH:mm:ss.
Optional custom time options. Use strings such as 09:30 or records with value, label, and disabled.
Popover Props
bottom-start
Props passed to the inner DomPopover. Time selector defaults position to bottom-end, max width to 18rem, padding to p-2, and arrow to true.
Field props
Optional ID override. By default parent forms derive the input ID from the field path using underscores.
Local field name. Parent forms derive the full field path and native HTML name from the form hierarchy.
Visible field label.
Optional helper copy below the field.
Placeholder shown when the control is empty.
Validation errors for this field.
Validators
No validators yet.
Validators attached to this field. Use functions in Vue code, or serializable records such as { name: "minLength", props: { min: 2 } } in generated schemas.
Render default field chrome, or hide chrome while keeping form state wiring.
npm install @getdom/studio<script setup>
import '@getdom/studio/style.css';
import { reactive } from 'vue';
import { DomTimeSelector } from '@getdom/studio';
const data = reactive({
"modelValue": "09:30",
"id": "",
"name": "",
"label": "Meeting time",
"description": "Type a time or choose one from the generated list.",
"placeholder": "",
"required": false,
"disabled": false,
"readOnly": false,
"invalid": false,
"errors": [],
"visible": true,
"validators": [],
"validateOnBlur": true,
"chrome": "field",
"timeFormat": "24h",
"minuteStep": 15,
"min": "08:00",
"max": "18:00",
"options": [],
"showSeconds": false,
"nativeInput": true,
"registerField": true,
"popoverProps": {}
});
</script>
<template>
<DomTimeSelector
v-bind="data"
@update:modelValue="data.modelValue = $event"
/>
</template>Demo
Generated business hours
Generate a selectable list from min, max, and minuteStep while still accepting typed times.
Type a time or choose one from the generated list.
Stored value: 09:30
npm install @getdom/studio<script setup>
import '@getdom/studio/style.css';
import { ref } from 'vue';
import { DomTimeSelector } from '@getdom/studio';
const time = ref('09:30');
</script>
<template>
<div class="max-w-sm space-y-4">
<DomTimeSelector
v-model="time"
name="meeting_time"
label="Meeting time"
description="Type a time or choose one from the generated list."
:min="'08:00'"
:max="'18:00'"
:minute-step="15"
/>
<p class="rounded-xl border border-border bg-secondary px-3 py-2 text-sm text-muted-fg">
Stored value:
<code class="font-mono text-canvas-fg">{{ time || 'empty' }}</code>
</p>
</div>
</template>
Demo
12-hour labels
Display 12-hour labels with AM and PM while storing the canonical HH:mm value.
Display options in 12-hour time while storing HH:mm.
Stored value: 14:30
npm install @getdom/studio<script setup>
import '@getdom/studio/style.css';
import { ref } from 'vue';
import { DomTimeSelector } from '@getdom/studio';
const time = ref('14:30');
</script>
<template>
<div class="max-w-sm space-y-4">
<DomTimeSelector
v-model="time"
name="handoff_time"
label="Handoff time"
description="Display options in 12-hour time while storing HH:mm."
time-format="12h"
:min="'09:00'"
:max="'17:00'"
:minute-step="30"
/>
<p class="rounded-xl border border-border bg-secondary px-3 py-2 text-sm text-muted-fg">
Stored value:
<code class="font-mono text-canvas-fg">{{ time || 'empty' }}</code>
</p>
</div>
</template>
Reference
Props
Control props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
modelValue | string | string | '' | Selected time as HH:mm, or HH:mm:ss when showSeconds is enabled. |
timeFormat | '24h' | '12h' | string | '24h' | How times are displayed in the input and option list. |
minuteStep | number | number | 15 | Minute interval used to generate selectable options. |
min | string | string | '' | Minimum selectable time as HH:mm or HH:mm:ss. |
max | string | string | '' | Maximum selectable time as HH:mm or HH:mm:ss. |
optionsts | array | Array< | [] | Optional custom time options. Use strings such as 09:30 or records with value, label, and disabled. |
showSeconds | boolean | boolean | false | Store and display seconds in addition to hours and minutes. |
nativeInput | boolean | boolean | true | Include the native input name for HTML form submission. |
registerField | boolean | boolean | true | Register with a parent form. Disable when composing this inside another form control. |
popoverProps | object | Record<string, unknown> | {} | Props passed to the inner DomPopover. Time selector defaults position to bottom-end, max width to 18rem, padding to p-2, and arrow to true. |
Field props
| Name | Type | TS | Default | Description |
|---|---|---|---|---|
id | string | string | '' | Optional ID override. By default parent forms derive the input ID from the field path using underscores. |
name | string | string | '' | Local field name. Parent forms derive the full field path and native HTML name from the form hierarchy. |
label | string | string | '' | Visible field label. |
description | string | string | '' | Optional helper copy below the field. |
placeholder | string | string | '' | Placeholder shown when the control is empty. |
required | boolean | boolean | false | Mark the field as required. |
disabled | boolean | boolean | false | Disable field interaction. |
readOnly | boolean | boolean | false | Show the value but prevent editing. |
invalid | boolean | boolean | false | Mark the field invalid. |
errorsts | array | object | string | Array< | [] | Validation errors for this field. |
visible | boolean | boolean | true | Show or hide the field. |
validators | array | Array<unknown> | [] | Validators attached to this field. Use functions in Vue code, or serializable records such as { name: "minLength", props: { min: 2 } } in generated schemas. |
validateOnBlur | boolean | boolean | true | Run validators when the field loses focus. |
chrome | 'field' | 'none' | false | string | 'field' | Render default field chrome, or hide chrome while keeping form state wiring. |
Auto-generated from Time selector.props and inline _edit hints.
Events
| Name | Payload | Description |
|---|---|---|
| @update:modelValue | HH:mm | Fired when a valid time is committed or selected. |
| @change | HH:mm | Fired when a valid time is committed. |
| @invalid-time | string | Fired when typed text cannot be parsed or is outside the allowed range. |
| @focus | FocusEvent | Fired when the text input receives focus. |
| @blur | FocusEvent | Fired when the text input loses focus. |
Names auto-detected from defineEmits and source emit() calls; payload and description from __doc.events when present.
Keyboard
- Alt + ArrowDownOpen the time list.
- EnterCommit the typed time when it is valid.
- EscClose the popover.
- TabMove through generated time options when the list is open.