Vitral 0.2
Form

TimePicker

A time of day, typed freely or picked from a list, and kept as minutes past midnight rather than a Date.

Import

main.ts
import { TimePicker } from '@vitral/vue';

Default

Half-hourly by default. The box shows the time the way the locale writes it; the value underneath is a number.

540 minutes past midnight
<script setup lang="ts">import { StackPanel, TimePicker } from '@vitral/vue';import { computed, ref } from 'vue'; const start = ref<number | null>(540);const nights = computed(() => (start.value === null ? '' : `${start.value} minutes past midnight`));</script> <template>    <StackPanel spacing="1rem">        <TimePicker v-model="start" aria-label="Start time" />        <small style="color: var(--vt-text-muted-color)">{{ nights }}</small>    </StackPanel></template>

Typed, not chosen

A time box is a place people type. Try `9`, `930`, `9:30`, `9h30`, `21:30` or `9 pm` — then leave the box. Something that names no time empties it rather than guessing.

Reads as nothing
<script setup lang="ts">import { formatMinutes } from '@vitral/core';import { StackPanel, TimePicker } from '@vitral/vue';import { ref } from 'vue'; const typed = ref<number | null>(null);const show = (minutes: number | null) => (minutes === null ? 'nothing' : formatMinutes(minutes, { hour12: false }));</script> <template>    <StackPanel spacing="1rem">        <TimePicker v-model="typed" placeholder="Type a time" aria-label="Any time" />        <small style="color: var(--vt-text-muted-color)">Reads as {{ show(typed) }}</small>    </StackPanel></template>

Bounded, and stepped

`min-time` and `max-time` decide what the list offers and clamp what is typed; `step` decides how close together the times are. Page Up and Page Down move the value itself by an hour.

<script setup lang="ts">import { TimePicker } from '@vitral/vue';import { ref } from 'vue'; const office = ref<number | null>(null);</script> <template>    <TimePicker v-model="office" :step="15" min-time="09:00" max-time="17:00" show-clear-button aria-label="Office hours" /></template>

Twelve or twenty-four

`hour12` overrides what the locale would have written. The list and the box always agree, because both are built from the same number.

<script setup lang="ts">import { TimePicker } from '@vitral/vue';import { ref } from 'vue'; const twelve = ref<number | null>(1290);</script> <template>    <div style="display: flex; gap: 1rem; flex-wrap: wrap">        <TimePicker v-model="twelve" :hour12="true" aria-label="Twelve hour" />        <TimePicker v-model="twelve" :hour12="false" aria-label="Twenty-four hour" />    </div></template>

Inline

Without the text box or the popup.

  • 12:00 AM
  • 1:00 AM
  • 2:00 AM
  • 3:00 AM
  • 4:00 AM
  • 5:00 AM
  • 6:00 AM
  • 7:00 AM
  • 8:00 AM
  • 9:00 AM
  • 10:00 AM
  • 11:00 AM
  • 12:00 PM
  • 1:00 PM
  • 2:00 PM
  • 3:00 PM
  • 4:00 PM
  • 5:00 PM
  • 6:00 PM
  • 7:00 PM
  • 8:00 PM
  • 9:00 PM
  • 10:00 PM
  • 11:00 PM
<script setup lang="ts">import { TimePicker } from '@vitral/vue';import { ref } from 'vue'; const inline = ref<number | null>(600);</script> <template>    <TimePicker v-model="inline" :step="60" inline aria-label="Pick an hour" /></template>

API

Read from packages/vue/src/components/TimePicker/types.ts, so it says what the component actually accepts.

Props

NameTypeDescription
stepnumberMinutes between the times the list offers. Defaults to 30.
minTimenumber | string | nullThe earliest time, as minutes past midnight or `'09:00'`.
maxTimenumber | string | nullThe latest, likewise.
hour12booleanForce twelve- or twenty-four-hour; defaults to what the locale writes.
secondsbooleanShow seconds in what is written; the list is still built from `step`.
placeholderstring—
inlinebooleanShow the list in place, without a text box or popup.
showClearButtonbooleanA footer button that empties the value.
sizeSize—
variantInputVariantDefaults to the plugin's `inputVariant`.
invalidboolean—
disabledboolean—
readonlyboolean—
fluidboolean—
placementOverlayPlacement—
appendTostring`'body'` (the default), `'self'` to render in place, or a selector.

Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.

Emits

EventPayloadDescription
timeSelectminutes: numberA time was chosen from the list, or typed and committed.
clear——
show——
hide——
focusevent: FocusEvent—
blurevent: FocusEvent—

Slots

NameSlot propsDescription
dropdownicon—The icon in the button that opens the list.
option(props: { minutes: number; label: string; selected: boolean })One time in the list.
footer(props: { minutes: number | null; clear: () => void })Under the list: a note, a pair of buttons.