ComponentsPickers

Time picker

A time of day for meetings, shifts, pickups and opening hours. Segmented input where each part is a spinbutton (type digits, ↑ ↓, ← →), an optional slot list every N minutes, and a start–end range with duration. The value is always "HH:mm" 24h; the display follows the locale (2:30 PM / 14:30).

WAI-ARIA spinbutton + Radix Popover components/time-picker.tsx, lib/date.tstheme · material · accent · density · font
1430

Type digits or use ↑ ↓.

value: 14:30

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { Field, TimePicker } from "@vamos-ui/react";

<Field label="Meeting starts">
  <TimePicker value={time} onValueChange={setTime} slots step={30} />
</Field>

Each segment is role="spinbutton" with aria-valuenow / min / max / valuetext inside a role="group" labelled by the Field. Digits type ahead and auto-advance; Backspace clears a segment, then moves back; : or . jumps to the next segment; A / P set the period.

The input group is always dir="ltr" so times read the same in right-to-left pages.

Examples

Slot list

slots opens a listbox every step minutes between min and max; disabledTimes greys out a lunch break.

––––––

Store open 09:00–18:00, every 30 minutes.

12-hour and 24-hour

Segment order, separator and AM/PM labels come from Intl. Both fields share one "HH:mm" value.

0745PM

Press A or P to switch.

1945

Same value, 24-hour display.

Shift start and end

TimeRangePicker shows the duration and flags an end before the start, unless overnight is set (then +1 day).

0900
1730
8 h 30 min

Front desk, Monday to Friday.

2200
0600
8 h+1 day

Ends the next morning.

Seconds, sizes & states

seconds adds a segment; disabled, read-only, out of range (aria-invalid) and sizes.

081530
1200
1800
2330

Opening hours are 10:00–22:00.

––––
0705

API

TimeInput / TimePicker

PropTypeDefault
value / defaultValue
"HH:mm" ("HH:mm:ss" with seconds), 24h.
string | null—
onValueChange
A complete time, or null when emptied or left incomplete.
(value: string | null) => void—
hourCycle
Display only. Default from the locale (en-US 12, tr 24).
12 | 24—
step
Minutes per ↑ / ↓ on the minute segment and between slots.
number1 (TimeInput) · 15 (TimePicker)
seconds
Adds a seconds segment.
booleanfalse
min / max
Allowed range (HH:mm). Outside it the group is aria-invalid.
string—
disabledTimes
Times that are not allowed (also disabled in the slot list).
(time: string) => boolean—
slots
TimePicker only: slot list popover.
booleanfalse
slotRange
TimePicker only: first / last slot. Default min / max or the whole day.
{ start: string; end: string }—
name
Hidden input submitting HH:mm.
string—
size / variant
Box look (controlVariants).
"sm" | "md" | "lg" / "default" | "ghost""md" / "default"
invalid / disabled / readOnly / required
Also read from Field.
boolean—
icon / trailing
Leading icon (null hides the clock) and end content.
ReactNode—
labels
timePicker namespace: hour, minute, second, dayPeriod, showTimes, durations.
Partial<TimePickerLabels>—

TimeRangePicker

PropTypeDefault
value / defaultValue
Two HH:mm values.
{ start: string | null; end: string | null }—
onValueChange
Any change of either end.
(value: TimeRange) => void—
overnight
An earlier end means the next day (night shift).
booleanfalse
showDuration
Duration hint, announced politely.
booleantrue
nameStart / nameEnd
Hidden inputs.
string—