Time Picker
Use @schedulespark/time-picker for framework-free analog and digital time inputs.
Time Picker
@schedulespark/time-picker provides framework-free analog and digital time picker modes for ScheduleSpark forms.
Related terms: npm, ScheduleSpark, @schedulespark/time-picker, time picker, timepicker, time input, analog time picker, digital time picker, scheduling, shift scheduling, 12-hour time, 24-hour time, minute step, min time, max time, keyboard input, CSS variables, forms, vanilla JavaScript, framework-free, TypeScript.
Install
npm install @schedulespark/time-pickerImport the stylesheet once wherever your app loads global CSS:
import "@schedulespark/time-picker/styles.css";The package is framework-free and has no runtime dependencies.
Basic Usage
import { createTimePicker } from "@schedulespark/time-picker";
import "@schedulespark/time-picker/styles.css";
const host = document.querySelector("#time-picker");
if (!(host instanceof HTMLElement)) {
throw new Error("Missing #time-picker host");
}
const picker = createTimePicker({
label: "Start time",
value: "09:00",
minTime: "06:00",
maxTime: "18:00",
minuteStep: 15,
mode: "analog",
onChange: (value) => {
console.log(value);
}
});
picker.mount(host);onChange always receives normalized HH:mm, regardless of whether the picker displays 12-hour or 24-hour labels.
Analog And Digital Modes
| Mode | Best for | Notes |
|---|---|---|
analog | Quick selection with a compact visual clock. | Pointer movement snaps to minuteStep; hour/minute controls respect minTime and maxTime. |
digital | Dense, predictable lists and keyboard-heavy forms. | Renders step-based options; out-of-range options are disabled. |
You can switch modes by recreating the picker with a different mode value. Values remain HH:mm.
API Reference
type TimePickerMode = "analog" | "digital";
type TimeFormat = "12h" | "24h";
interface TimePickerOptions {
disabled?: boolean;
id?: string;
label?: string;
maxTime?: string;
minTime?: string;
minuteStep?: number;
mode?: TimePickerMode;
name?: string;
onChange?: (value: string) => void;
placeholder?: string;
required?: boolean;
timeFormat?: TimeFormat;
value?: string;
}| Option | Type | Default | Notes |
|---|---|---|---|
value | string | "" | Current time as HH:mm. |
onChange | (value: string) => void | undefined | Receives normalized HH:mm. |
mode | "analog" | "digital" | "analog" | Picker UI mode. |
timeFormat | "24h" | "12h" | "24h" | Display format only. Values remain HH:mm. |
minuteStep | number | 15 | Digital option interval and analog snap step. |
minTime | string | undefined | Inclusive lower bound as HH:mm. |
maxTime | string | undefined | Inclusive upper bound as HH:mm. |
label | string | undefined | Optional field label. |
id | string | generated | Input id. |
name | string | undefined | Input name for native form submission. |
placeholder | string | undefined | Input placeholder. |
required | boolean | false | Native required attribute. |
disabled | boolean | false | Disables input and picker controls. |
Instance Methods
| Method | Notes |
|---|---|
mount(host) | Renders into an HTMLElement. |
setValue(value) | Updates the selected value. |
setDisabled(disabled) | Toggles disabled state. |
destroy() | Removes the picker DOM. |
Range Rules
- Values must be valid day times from
00:00through23:59. minTimeandmaxTimeare inclusive.- Typed values are normalized to
HH:mm. timeFormataffects display labels only.- Use
maxTime: "11:59"for 11:59 AM andmaxTime: "23:59"for 11:59 PM. - Digital values outside the range remain visible but disabled.
12-Hour Display
createTimePicker({
label: "Close time",
value: "17:30",
timeFormat: "12h",
minTime: "09:00",
maxTime: "23:00",
onChange(value) {
// value is still "HH:mm", for example "17:45"
}
});Theming
Override CSS custom properties on .ssp-time-picker:
| Variable | Default | Affects |
|---|---|---|
--ssp-time-picker-text | #18211f | Root text and button text. |
--ssp-time-picker-label-text | #33413d | Field label. |
--ssp-time-picker-border | #c7d1cc / #d8e0dc | Input, button, popover, and clock borders. |
--ssp-time-picker-bg | #fff | Button, popover, and clock backgrounds. |
--ssp-time-picker-accent | #11735f | Focus ring, selected border, and clock center. |
--ssp-time-picker-accent-bg | #dff4eb | Active and selected backgrounds. |
--ssp-time-picker-accent-text | #0a4f42 | Active and selected text. |
--ssp-time-picker-disabled-bg | #eef2f0 | Disabled button background. |
--ssp-time-picker-disabled-text | #8a9692 | Disabled button text. |
--ssp-time-picker-radius | 0.5rem | Popover radius. |
--ssp-time-picker-popover-shadow | package default | Popover shadow. |
--ssp-time-picker-z-index | 20 | Popover stacking order. |
--ssp-time-picker-popover-min-width | 16rem | Popover minimum width. |
--ssp-time-picker-popover-max-width | min(94vw, 22rem) | Popover maximum width. |
--ssp-time-picker-clock-size | min(17rem, 78vw) | Analog clock size. |
.dark-form .ssp-time-picker {
--ssp-time-picker-text: #e7f1ee;
--ssp-time-picker-label-text: #b7c4bf;
--ssp-time-picker-border: #33413d;
--ssp-time-picker-bg: #17211e;
--ssp-time-picker-accent: #4fd1a5;
--ssp-time-picker-accent-bg: #163a2f;
--ssp-time-picker-accent-text: #8ff0c7;
}Framework Integration
Mount once after the host element exists and destroy on unmount. In React, store the picker instance in a ref and call setValue or setDisabled from effects when props change.
Troubleshooting
| Symptom | Check |
|---|---|
| Value is AM/PM text | The API expects and emits HH:mm; timeFormat only changes display labels. |
| Options are disabled | Confirm minTime, maxTime, and minuteStep produce selectable values. |
| Popover appears behind another layer | Raise --ssp-time-picker-z-index. |
| Styles are missing | Import @schedulespark/time-picker/styles.css. |