Skip to content

Time picker

Choose hours and minutes or type a time such as 2:30p or 1430. A valid time is kept even if it is not among the listed options.

Pick in the columns, or type 2:37p or 1437.

Not before the start.

Every 15 minutes, from 8 to noon.

24 hours, whatever the language.

10 PM to 6 AM, across midnight.

<script setup lang="ts">import { ref } from 'vue'import { UiField, UiTimePicker } from 'grani' const start = ref('10:30') const end = ref('12:30') const work = ref('09:00') const departs = ref('14:30') const night = ref('23:00')</script> <template>  <div class="flex w-72 max-w-full flex-col gap-6">    <UiField label="Starts at" description="Pick in the columns, or type 2:37p or 1437.">      <UiTimePicker v-model="start" class="w-full" />    </UiField>    <UiField label="Ends at" description="Not before the start.">      <UiTimePicker v-model="end" :min="start" class="w-full" />    </UiField>    <UiField label="Opens at" description="Every 15 minutes, from 8 to noon.">      <UiTimePicker v-model="work" :step="15" min="08:00" max="12:00" class="w-full" />    </UiField>    <UiField label="Departs at" description="24 hours, whatever the language.">      <UiTimePicker v-model="departs" :hour-cycle="24" class="w-full" />    </UiField>    <UiField label="Night shift starts" description="10 PM to 6 AM, across midnight.">      <UiTimePicker v-model="night" min="22:00" max="06:00" :step="30" class="w-full" />    </UiField>  </div></template>

Also called time input, time field.

Usage

<UiTimePicker />

With GraniResolver in the Vite config, a template needs no import: set it up once.

API

Name · typeDefaultDescription
Value
modelValuestring | null= nullnullThe time, HH:mm (v-model); null for none.
Behavior
stepnumber= 55Minutes between two rows of the Minute column.
minstring= "00:00""00:00"The first time the window allows, HH:mm.
maxstring= "23:59""23:59"The last time the window allows, HH:mm; a min after it wraps the window past midnight.
clearableboolean= falsefalseA cross that empties the field.
hourCycle12 | 2412 hours with an AM/PM column, or 24; unset, the app's language decides (2:30 PM in American English, 14:30 in Russian). The field writes the time the same way.
Look
placeholderstring= """"Shown while empty; defaults to "Pick a time".
sizexs | sm | mdStep of the control ladder. Unset, the app's size (createGrani({ size })), sm by default.
Form and access
disabledboolean= falsefalseThe field cannot be changed.
requiredboolean= falsefalseStandalone only: empty is an error, said to a reader, and no cross. Inside UiField the field's required says so.
invalidboolean= falsefalseStandalone only: the value is wrong. Inside UiField the field's error says so.
namestringSends the time with a form, under this name.
idstringId of the trigger, standalone; inside UiField the field's id wins.
ariaLabelstringStandalone only: the accessible name. Inside UiField the label names it.

Attributes: class and style stay on the outer element; the rest (native attributes, aria-*, data-testid) reach the control inside it.

When to use another component

When you needTake
A dayDate picker
A duration in minutesInput numeric
Any other pick from a listSelect itself