TimePicker

Lets users select a specific time from a list or enter a custom value. Supports 12/24-hour formats, custom intervals, and optional time ranges.

Basic

Meeting time
Selected: 14:30

24 Hour Format

Nightly backup runs at
UTC, every day at 02:00

Custom Options

Book a class

Min / Max Range

Shift hours
From
To
Working 09:00 – 17:00

API Reference

Show types
typescript
/**
 * TimePicker is a thin wrapper around Combobox that adds time-aware parsing,
 * generated options, and a 12/24-hour display toggle. Canonical value is
 * always 24-hour `HH:mm` (or `HH:mm:ss` if seconds were typed).
 */

export type PopoverSide = 'top' | 'right' | 'bottom' | 'left'
export type PopoverAlign = 'start' | 'center' | 'end'

export type Placement =
  | 'bottom-start'
  | 'top-start'
  | 'top-end'
  | 'bottom-end'
  | 'right-start'
  | 'right-end'
  | 'left-start'
  | 'left-end'

export type Variant = 'outline' | 'subtle'

export interface TimePickerProps {
  /** Controlled value, canonical `HH:mm` (or `HH:mm:ss`). */
  modelValue?: string

  /**
   * Uncontrolled initial value.
   * @deprecated Use `modelValue` with `v-model` instead.
   */
  value?: string

  /** Minute interval between generated options. */
  interval?: number

  /** Caller-provided option values; bypasses the generated grid. */
  options?: Array<{ value: string; label?: string }>

  /** Preferred popover side. */
  side?: PopoverSide

  /** Alignment of the popover along the trigger edge. */
  align?: PopoverAlign

  /** Gap between trigger and popover in pixels. */
  offset?: number

  /**
   * Combined side+align placement.
   * @deprecated Use `side` and `align` instead.
   */
  placement?: Placement

  /** Placeholder text when no value is selected. */
  placeholder?: string

  /** Visual style variant. */
  variant?: Variant

  /**
   * Whether the trigger input accepts typed input. When `false` the user can
   * still open the popover and pick a time, but cannot type a time manually.
   * Default: `true`.
   */
  typeable?: boolean

  /**
   * Prevents manual typing while keeping the picker interactive.
   * @deprecated Use `typeable: false` instead.
   */
  readonly?: boolean

  /**
   * Allows users to type custom time values.
   * @deprecated Use `typeable: false` instead.
   */
  allowCustom?: boolean

  /** Keeps the popover open after a time is selected. */
  keepOpen?: boolean

  /**
   * Closes the popover after a value is picked.
   * @deprecated Use `keepOpen` (inverse semantics).
   */
  autoClose?: boolean

  /** Use 12-hour (am/pm) format for display. */
  use12Hour?: boolean

  /** Disable the time picker. */
  disabled?: boolean

  /** Controlled popover open state. Use with `v-model:open` for two-way binding. */
  open?: boolean

  /** Opens the popover when the input receives focus. Default: false. */
  openOnFocus?: boolean

  /** Opens the popover when the input is clicked. Default: true. */
  openOnClick?: boolean

  /** Minimum selectable time as `HH:mm[:ss]`. */
  min?: string

  /** Maximum selectable time as `HH:mm[:ss]`. */
  max?: string

  /**
   * Minimum selectable time as `HH:mm[:ss]`.
   * @deprecated Use `min` instead.
   */
  minTime?: string

  /**
   * Maximum selectable time as `HH:mm[:ss]`.
   * @deprecated Use `max` instead.
   */
  maxTime?: string

  /**
   * Scroll behavior when opening the list.
   * @deprecated Scrolling is always centered now.
   */
  scrollMode?: 'center' | 'start' | 'nearest'
}

export type TimePickerEmits = {
  (e: 'update:modelValue', value: string): void
  (e: 'update:open', value: boolean): void
  (e: 'change', value: string): void
  (e: 'input-invalid', input: string): void
  (e: 'invalid-change', invalid: boolean): void
  (e: 'open'): void
  (e: 'close'): void
}
Prop Default Type
modelValue
""
string

Controlled value, canonical `HH:mm` (or `HH:mm:ss`).

value

Deprecated — Use `modelValue` with `v-model` instead.

interval
15
number

Minute interval between generated options.

options
[]
{ value: string; label?: string; }[] | undefined

Caller-provided option values; bypasses the generated grid.

side
PopoverSide

Preferred popover side.

align
PopoverAlign

Alignment of the popover along the trigger edge.

offset
number

Gap between trigger and popover in pixels.

placement

Deprecated — Use `side` and `align` instead.

placeholder
"Select time"
string

Placeholder text when no value is selected.

variant
"subtle" as Variant
Variant

Visual style variant.

typeable
true
boolean

Whether the trigger input accepts typed input. When `false` the user can still open the popover and pick a time, but cannot type a time manually. Default: `true`.

readonly
false

Deprecated — Use `typeable: false` instead.

allowCustom
true

Deprecated — Use `typeable: false` instead.

keepOpen
boolean

Keeps the popover open after a time is selected.

autoClose
true

Deprecated — Use `keepOpen` (inverse semantics).

use12Hour
true
boolean

Use 12-hour (am/pm) format for display.

disabled
false
boolean

Disable the time picker.

open
boolean

Controlled popover open state. Use with `v-model:open` for two-way binding.

openOnFocus
false
boolean

Opens the popover when the input receives focus. Default: false.

openOnClick
true
boolean

Opens the popover when the input is clicked. Default: true.

min
string

Minimum selectable time as `HH:mm[:ss]`.

max
string

Maximum selectable time as `HH:mm[:ss]`.

minTime

Deprecated — Use `min` instead.

maxTime

Deprecated — Use `max` instead.

scrollMode

Deprecated — Scrolling is always centered now.

Slot Payload
prefix

Rendered inside the trigger input, before the typed value.

suffix
{ togglePopover: () => void; isOpen: boolean; }

Rendered inside the trigger input, after the typed value. Defaults to a chevron-down that toggles the popover.

Event Payload
update:modelValue
[value: string]

Fired when the model value changes.

change
[value: string]

Fired after the value is committed.

open
[]

Fired when the component opens.

update:open
[value: boolean]

Fired when the open state changes.

close
[]

Fired when the component closes.

input-invalid
[input: string]
invalid-change
[invalid: boolean]