Guide
Getting started
npm install @devix-labs/time-picker
<label for="at">Appointment</label>
<input id="at" name="at" value="09:30">
import { createTimePicker } from '@devix-labs/time-picker';
import '@devix-labs/time-picker/styles.css';
const picker = createTimePicker(document.querySelector('#at'), {
min: '09:00',
max: '17:00',
step: 30,
disabled: [['12:00', '13:00']], // lunch
onChange: (value) => console.log(value), // "14:30"
});
The input you point at keeps its label and posts the time under its own name, as HH:mm. It shows
the time the way the person's locale writes it — 5:30 PM in Chicago, 17:30 in Manchester,
٥:٣٠ م in Dubai — while the value your server receives is always the same 24-hour string.
The value
Always "HH:mm", or "HH:mm:ss" with seconds: true. Never a Date: a Date is an instant, so
"09:00" becomes a different time when a server in another zone reads it, and it moves an hour twice
a year. Here a time is just a time.
picker.getValue(); // "14:30"
picker.getTime(); // 52200 — seconds since midnight, for arithmetic
picker.setValue('09:15');
picker.setValue(null);
Which times are on offer
createTimePicker(input, {
min: '09:00',
max: '17:00',
step: 30, // minutes
disabled: [
['12:00', '13:00'], // a span
'15:30', // one time
(seconds) => seconds % 3600 !== 0, // or a rule of your own
],
});
A span that runs backwards crosses midnight, which is how a kitchen that shuts at eleven is written:
createTimePicker(input, { disabled: [['23:00', '06:00']] });
Unavailable times are shown struck through rather than hidden. A list with the middle missing tells nobody anything; a list with "12:30" crossed out says the place is shut for lunch.
enabled is the other way round — an allow-list — and disabled still overrides it.
Booking, where each slot is different
createTimePicker(input, {
slots: [
{ time: '09:00', note: '3 left' },
{ time: '09:30', disabled: true, reason: 'fully booked' },
{ time: '10:00', note: 'AED 250', className: 'is-premium' },
],
});
reason is read out by a screen reader, so the row is not just mysteriously dead.
Typing
The field is a real text input, so a phone keyboard, a paste and a password manager all work. It takes what people actually type:
5pm 5 PM 5p 17:30 1730 530 5.30 5:3 7h30 noon midnight now
٥:٣٠ م ۱۷:۳۰
When "5" could be either five, the picker asks which one it would accept. In a shop open from nine
to six, 5 can only mean the afternoon — so that is what you get. Where both work, it stays in the
half of the day the field is already in.
Enter applies the time. It does not submit the form the picker is sitting in.
A range
import { createTimeRangePicker } from '@devix-labs/time-picker';
createTimeRangePicker(document.querySelector('#opens'), {
endInput: document.querySelector('#closes'),
step: 30,
minDuration: 60,
onChange: ({ start, end }) => save(start, end),
});
Picking the start moves you on to the end field, ends that would make the range too short are
already struck out, and the panel says how long it is. overnight: true lets a shift run past
midnight; getDuration() returns its length in seconds either way.