Components / Forms

TimePicker

A compact custom time picker with step-aware hour, minute, and second lists.

Preview

Install

Run in your project
Package manager
npx @getweini/cli@latest add time-picker

Use cases

Office hours

Choose a wall-clock time in a bounded daily interval.

Meeting start

Present a localized time while storing a canonical HH:mm value.

Usage example

Vue
<script setup lang="ts">
import { ref } from 'vue'
import TimePicker from './components/ui/time-picker/TimePicker.vue'
const time = ref('')
</script>

<template>
  <label for="appointment-time">Appointment time</label>
  <TimePicker
    id="appointment-time"
    v-model="time"
    name="time"
    min="09:00"
    max="17:00"
    :step="900"
    :messages="{
      timePickerLabel: 'Choose an appointment time',
      chooseTime: 'Choose time',
      hoursLabel: 'Hours',
      minutesLabel: 'Minutes',
      secondsLabel: 'Seconds',
      clearSelection: 'Clear time',
    }"
  />
</template>

More examples

Quarter-hour appointment

step is seconds, so 900 gives 15-minute choices.

Quarter-hour appointment
<script setup lang="ts">
import { ref } from 'vue'
import TimePicker from './components/ui/time-picker/TimePicker.vue'
const time = ref('')
const messages = {
  timePickerLabel: 'Choose appointment time', chooseTime: 'Choose time', hoursLabel: 'Hours',
  minutesLabel: 'Minutes', secondsLabel: 'Seconds', clearSelection: 'Clear time',
}
</script>
<template>
  <label for="appointment-time">Appointment time</label>
  <TimePicker id="appointment-time" v-model="time" name="time" min="09:00" max="17:00" :step="900" locale="en-GB" :messages="messages" />
</template>

US local meeting time

Locale affects display, while an IANA zone belongs to the event record.

US local meeting time
<script setup lang="ts">
import { ref } from 'vue'
import TimePicker from './components/ui/time-picker/TimePicker.vue'
const time = ref('09:30')
const timeZone = ref('America/New_York')
const messages = {
  timePickerLabel: 'Choose meeting time', chooseTime: 'Choose time', hoursLabel: 'Hours',
  minutesLabel: 'Minutes', secondsLabel: 'Seconds', clearSelection: 'Clear time',
}
</script>
<template>
  <label for="meeting-time">Meeting time in New York</label>
  <TimePicker id="meeting-time" v-model="time" locale="en-US" :messages="messages" />
  <input type="hidden" name="timeZone" :value="timeZone" />
</template>

Key API

The most useful props, models, slots, events, and methods for this component.

Key API for TimePicker
NameTypeDefault or requirement
v-modelHH:mm or HH:mm:ss string''
sizesm | md | lgmd
invalid / disabled / readonly / requiredbooleanfalse
min / maxHH:mm or HH:mm:ss stringundefined
stepnumber, seconds60
localeIntl locale stringHH:mm or HH:mm:ss display
messagesTimePickerMessagesrequired

The custom lists support arrows, Home/End, and Escape, while an off-screen native time control preserves form serialization and constraints. Seconds appear when the value or step requires them.

Implementation notes

  • The model stores HH:mm or HH:mm:ss, not a timezone-aware instant. step uses seconds.
  • For an event, store date, time, and IANA timezone separately; resolve daylight-saving ambiguity when creating the instant.

Accessibility and localization

  • Localize all panel labels and clear text. Name the time control and include the timezone in nearby help when it matters.
Weini UIDesign system · Vue component library · Free and public