Time Picker
Fast, keyboard-first time entry with locales and step rules.
npm install @devix-labs/time-picker
Times you can take away — exact times, spans that may cross midnight, or a rule — shown struck through with a reason rather than hidden. Booking slots with their own labels and notes. Typing that reads "5pm", "1730", "5.30", "noon" and ٥:٣٠ م, and resolves an ambiguous hour by what the picker would accept. A 12- or 24-hour clock taken from the locale through Intl. Other time zones read off the same clock, daylight saving included, with no date library. A range mode with durations. 9.1 kB gzip, zero dependencies, and the same behaviour in React, Vue, Svelte, a web component or a plain page.
What you get
Times you can take away
Exact times, [from, to] spans — including ones that cross midnight — or a rule of your own. The request the picker everyone uses has had open with 22 votes since 2018.
Booked slots say so
Give the list outright and each row carries its own label, note and reason: "3 left", "AED 250", "fully booked" — the last of which a screen reader reads out.
It reads what people type
5pm, 17:30, 1730, 5.30, 5:3, 7h30, noon, now, ٥:٣٠ م. Where "5" could be either five, it picks the one the day actually has open.
The locale's own clock
en-GB is 24-hour, en-US is 12-hour, ar-AE writes ص and م. One Intl call, and no flag for you to set wrong.
Other time zones, no library
Read the chosen time on as many clocks as you like, daylight saving included, and be told when it lands on another day. The second most-reacted request on flatpickr, answered in 40 lines.
A range that knows it is one
Picking the start moves you on to the end, ends that break minDuration are already struck out, the panel says how long it is, and a shift can run past midnight.
A value that cannot drift
Seconds since midnight, posted as HH:mm. Not a Date — which is an instant, and so is a different time on a server abroad and an hour out twice a year.
Usable on a phone, and by a keyboard
A bottom sheet with thumb-sized rows, a real combobox and listbox with aria-activedescendant, and a panel that does not spring open when you tab past it.
Time Picker — overview
Why it exists
A time picker is not a clock. It is a list of the times you can have, and almost every library treats that as an afterthought: the vanilla one most projects use has had "add a feature to disable specific hours and minutes" open with 22 votes since 2018, its most-reacted request after that is for time zones, and it has not shipped a release since April 2022. The alternatives are React-only, one of them last published in 2019. The jQuery one has had an issue called "Time Picker accessibility issues" open for years.
Meanwhile the thing people are building is a booking form.
What it does differently
- Times can be taken away. Exact times, spans — including ones that cross midnight, for a kitchen that shuts at eleven — or a rule of your own. Unavailable times are shown struck through with a reason, not hidden: a list with the middle missing tells nobody anything.
- Slots, with what is left on them. Give the list outright and each row carries its own label, note and reason — "3 left", "AED 250", "fully booked".
- It reads what people type. "5pm", "1730", "5.30", "5:3", "noon", "now", and Arabic-Indic digits with ص and م. Where "5" is ambiguous it asks which reading the picker would accept, so a shop open from nine means the afternoon.
- The clock comes from the locale.
en-GBis 24-hour,en-USis 12-hour,ar-AEwrites م — oneIntlcall, and every library here makes you set it by hand instead. - Other zones, no date library. The chosen time read on as many clocks as you like, daylight saving included, saying when it lands on another day.
- A value that cannot drift. Seconds since midnight, posted as
HH:mm. Not aDate, which is an instant, and so is a different time on a server in another country and an hour out twice a year. - 9.1 kB gzip, zero dependencies, with the core — parsing, formatting, slots and zones — usable on its own at 2.7 kB.
Not in 1.0
A duration field (2h 30m rather than a time of day) and a recurring-availability model (opening
hours per weekday) are both real, and both are a different product rather than more options on this
one. Pairing with a date for a full datetime is done by putting this next to the date picker; a
combined control would have to take a stance on time zones that neither of them should take alone.
Demos
All demos →Book an appointment
Half of these are taken, and you can see which — the thing the picker everyone uses has had open as a request...
Opening hours, in three places
A range that will not let you close before you open — and the same hours read on the clocks your customers are...
Fifteen languages
The same picker in every language the package ships — and each one reads its own word for noon, so “midi” and...
How it compares
Questions
Why not just use <input type="time">?
Because it cannot tell anyone which times are free. It also looks different in every browser, follows the operating system rather than your locale for 12- or 24-hour, and on iOS is a wheel. Mount this on the same input and you keep the field, the name and the HH:mm value, and gain the list.
What does the server receive?
"14:30", or "14:30:45" with seconds — in a hidden field under the input's own name. That is what a MySQL TIME column, Laravel's H:i and PHP's DateTime all expect.
How do I show only the slots that are free?
Pass them as `slots`, with `disabled` and a `reason` on the ones that are taken. They stay visible and struck through, which is what someone looking at a booking form needs to see. `getSlots()` hands the worked-out list back if you want to render your own summary.
Does the time zone feature need a date library?
No. The browser already knows every zone; Intl will give you a zone's offset at an instant if you ask it the right way, and going back the other way takes two passes. The whole thing is about 40 lines.
Can it do a duration, like 2h 30m?
Not in 1.0. A duration field is a different control from a time of day, and pretending otherwise is how pickers end up with options that contradict each other. The range mode does report durations.
More from Devix
All resources →Phone Input
UI component
International phone field with as-you-type formatting, validation and lazy per-country metadata.
Date Picker
UI component
Timezone-safe date picker with Hijri calendars, natural-language typing and a mobile sheet.
Date Range Picker
UI component
Ranges with presets, compare periods and multi-month views.