Forms · astro-ui · TimePickerNew
TimePickerJS
Time field with four interaction patterns: slot list, native input, scroll-drum wheel, and circular clock.
TimePicker covers every time-entry scenario with a single component. variant="select" builds a slot list from step — the shape appointment forms need. variant="input" hands off to the platform picker. variant="wheel" renders a scroll-snap column drum — the mobile-native feel on desktop. variant="clock" renders a circular clock face where you tap the hour hand, then the minute hand. All four write the same HH:mm value into a hidden form input, so the form contract never changes.
Features
- Four variants: `select` slots, native `input`, scroll `wheel`, circular `clock`
- Wheel: infinite-scroll snap drums with pointer drag, momentum, and mouse wheel
- Clock: SVG clock face — tap to set hour then minute; auto-advances between steps
- 24-hour and 12-hour (AM/PM) mode for both `wheel` and `clock`
- All variants write a hidden `HH:mm` input — same form contract everywhere
- `step`, `min`, and `max` bound the available slots (select/wheel)
- Labels formatted with `Intl` — 24-hour or 12-hour via `hour12`
- 3 sizes, invalid state, disabled and required support
Usage
---
import { TimePicker, Label } from "astro-ui";
---
<Label for="slot">Drop-off</Label>
<TimePicker id="slot" name="slot" step={30} min="09:00" max="17:00"/>
<!-- Wheel -->
<TimePicker name="appt" variant="wheel" hour12 />
<!-- Clock -->
<TimePicker name="start" variant="clock" value="09:30" />Demos
30-minute booking slots
<Label for="tp-slot">Drop-off</Label>
<TimePicker id="tp-slot" name="slot" step={30} min="09:00" max="17:00"/>12-hour labels
<Label for="tp-12">Reminder</Label>
<TimePicker
id="tp-12"
name="reminder"
step={15}
hour12
placeholder="Pick a reminder time"
/>Native time input
<Label for="tp-native">Starts at</Label>
<TimePicker id="tp-native" name="starts" variant="input" step={15} value="09:30"/>Wheel (scroll-drum) picker
<!-- 24-hour -->
<TimePicker variant="wheel" name="appt" value="14:30" />
<!-- 12-hour with AM/PM column -->
<TimePicker variant="wheel" name="appt" hour12 value="02:45" />Circular clock picker
<!-- 24-hour -->
<TimePicker variant="clock" name="meeting" value="09:30" />
<!-- 12-hour with AM/PM toggle -->
<TimePicker variant="clock" name="meeting" hour12 value="09:30" />API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "select" | "input" | "wheel" | "clock" | "select" | Interaction pattern. |
name | string | — | Form field name. |
value | string | — | Initial value (`HH:mm`). |
min | string | — | Earliest time (`HH:mm`) — select/wheel. |
max | string | — | Latest time (`HH:mm`) — select/wheel. |
step | number | 1 | Slot interval in minutes (select/wheel). |
hour12 | boolean | false | 12-hour display with AM/PM (wheel/clock/select). |
locale | string | "en-US" | Locale for slot labels (select). |
placeholder | string | "Select a time" | Empty option label (select variant). |
size | "sm" | "md" | "lg" | "md" | Control size (select/input/wheel). |
invalid | boolean | false | Sets `aria-invalid` and the error border. |
required | boolean | false | Required field. |
disabled | boolean | false | Disabled field. |
ariaLabel | string | — | Accessible name when there is no visible label. |
class | string | — | Merged via cn(); Tailwind classes welcome. |
id | string | — | Control id (use it in `<Label for>`). |
Accessibility
Implemented accessibility features — semantics, ARIA wiring, and keyboard behavior that ship with the component.
- Wheel and clock variants include a
role='region'witharia-label - Wheel has an
aria-liveregion that announces the current time after each change - Clock display buttons use
aria-pressedto convey active mode (hour vs minute) select/inputvariants use native elements — no custom widget to mis-keyaria-invalidaccompanies the invalid border on all variants- Give the control a
<Label for>orariaLabel
FAQ
How do I read the selected time from the wheel or clock?
Listen for `change` (or `input`) on the hidden `<input type="hidden">` inside the component, or read the form value by `name` on submit. The value is always `HH:mm`.
Does the wheel support touch?
Yes — the drum uses the Pointer Events API which covers mouse, touch, and stylus. `touch-action: none` is set on the drum so the page doesn't scroll while you spin it.
How do I submit a timezone?
Send the local wall-clock `HH:mm` plus a separate timezone field (or an ISO datetime) — a bare time has no zone, so the server must be told which one it is.
Can I combine it with DatePicker?
Yes — put a DatePicker and a TimePicker side by side with `name="date"` and `name="time"`, then combine them server-side.
Changelog
Version history mentioning TimePicker.
- Forms (18): Autocomplete, Combobox, Label, Field, Input, InputGroup, Textarea, Select, Checkbox, Radio, Switch, Toggle, ToggleGroup, RadioGroup, Rating, Slider, DatePicker, TimePicker.