timepicker-ui
4.7.0GitHub
timepicker-ui
API Reference / TypeScript

TypeScript

Full TypeScript support with type definitions

Installation

#

TypeScript definitions are included with the package:

index.ts
npm install timepicker-ui
// Types are automatically available
import { TimepickerUI } from 'timepicker-ui';
import type { TimepickerOptions, ConfirmEventData } from 'timepicker-ui';

Main Interfaces

#

TimepickerOptions

The grouped options object (v4.0.0+). Each group has its own exported interface: ClockOptions, UIOptions, LabelsOptions, BehaviorOptions, CallbacksOptions, TimezoneOptions, RangeOptions, WheelOptions and the deprecated ClearBehaviorOptions.

index.ts
interface TimepickerOptions {
clock?: ClockOptions; // type, increments, showSeconds, disabledTime, defaultTime, ...
ui?: UIOptions; // theme, mode, animation, backdrop, inline, clearButton, ...
labels?: LabelsOptions; // all UI text and accessibility labels
behavior?: BehaviorOptions; // focusTrap, returnFocus, delayHandler, id
callbacks?: CallbacksOptions; // onConfirm, onCancel, onOpen, onUpdate, ...
timezone?: TimezoneOptions; // timezone plugin config
range?: RangeOptions; // range plugin config
wheel?: WheelOptions; // wheel / compact-wheel mode config
clearBehavior?: ClearBehaviorOptions; // deprecated, use ui.clearButton
}
// All group interfaces are exported:
import type {
TimepickerOptions,
ClockOptions,
UIOptions,
LabelsOptions,
BehaviorOptions,
CallbacksOptions,
TimezoneOptions,
RangeOptions,
WheelOptions,
ClearBehaviorOptions,
} from 'timepicker-ui';

Event data types

Each event/callback has its own payload type. All of them are exported from 'timepicker-ui'. Fields marked showSeconds are present only when clock.showSeconds is on.

index.ts
type OpenEventData = {
hour: string;
minutes: string;
seconds?: string; // showSeconds
type?: string; // 'AM' or 'PM' (12h mode)
degreesHours: number | null; // deprecated, removed in 5.0
degreesMinutes: number | null; // deprecated, removed in 5.0
};
type ConfirmEventData = {
hour?: string;
minutes?: string;
seconds?: string; // showSeconds
type?: string;
autoCommit?: boolean; // true when triggered by wheel.commitOnScroll
};
type UpdateEventData = {
hour?: string;
minutes?: string;
seconds?: string; // showSeconds
type?: string;
};
type SelectSecondEventData = { // payload of 'select:second'
seconds: string;
};
type SelectPeriodEventData = { // payload of 'select:period'
type: 'AM' | 'PM';
};
type SwitchFaceEventData = { // payload of 'switch:face'
face: 'hours' | 'minutes' | 'seconds';
};
type CancelEventData = Record<string, never>; // empty payload
type ClearEventData = {
previousValue: string | null;
};
type ErrorEventData = {
error: string;
rejectedHour?: string; // deprecated, always undefined
rejectedMinute?: string; // deprecated, always undefined
inputHour?: string | number;
inputMinute?: string | number;
inputSecond?: string | number; // showSeconds
inputType?: string;
inputLength?: string | number;
};
type RangeConfirmEventData = {
from: string;
to: string;
duration: number; // whole minutes
durationSeconds?: number; // showSeconds, exact length in seconds
autoCommit?: boolean; // true when triggered by wheel.commitOnScroll
};
type RangeValidationEventData = {
valid: boolean;
duration: number; // whole minutes
durationSeconds?: number; // showSeconds, exact length in seconds
minDuration?: number;
maxDuration?: number;
};
type WheelScrollEndEventData = {
column: 'hours' | 'minutes' | 'seconds' | 'ampm';
value: string;
previousValue: string | null;
};
// Also exported: SelectHourEventData, SelectMinuteEventData,
// SelectAMEventData and SelectPMEventData (deprecated), ShowEventData,
// HideEventData (deprecated),
// TimezoneChangeEventData, RangeSwitchEventData,
// WheelScrollStartEventData
type SwitchViewEventData = { // payload of 'switch:view'
view: TimepickerView;
};
type RangeChangeEventData = { // payload of 'range:change'
part: 'from' | 'to';
from: RangeTimeValue | null;
to: RangeTimeValue | null;
};

TimepickerEventMap

Maps every event name to its payload type. picker.on / once / off are typed against this map, so handlers get the correct payload type automatically.

index.ts
import type { TimepickerEventMap } from 'timepicker-ui';
interface TimepickerEventMap {
open: OpenEventData;
cancel: CancelEventData;
confirm: ConfirmEventData;
clear: ClearEventData;
show: ShowEventData;
hide: HideEventData; // deprecated, never emitted
update: UpdateEventData;
'select:hour': SelectHourEventData;
'select:minute': SelectMinuteEventData;
'select:second': SelectSecondEventData;
'select:period': SelectPeriodEventData;
'select:am': SelectAMEventData; // deprecated, use 'select:period'
'select:pm': SelectPMEventData; // deprecated, use 'select:period'
'switch:face': SwitchFaceEventData;
'switch:view': SwitchViewEventData;
'timezone:change': TimezoneChangeEventData;
'range:confirm': RangeConfirmEventData;
'range:switch': RangeSwitchEventData;
'range:validation': RangeValidationEventData;
'range:change': RangeChangeEventData; // new in 4.7.0
'wheel:scroll:start': WheelScrollStartEventData;
'wheel:scroll:end': WheelScrollEndEventData;
error: ErrorEventData;
// ...plus internal animation/range coordination events
}

getValue() return shape

The object returned by picker.getValue(). seconds is present only with clock.showSeconds, and time then includes it.

index.ts
{
hour: string;
minutes: string;
seconds?: string; // showSeconds
type?: string; // 'AM' or 'PM' (12h mode)
time: string; // '14:30', '02:30 PM', '14:30:15', '02:30:15 PM'
degreesHours: number | null; // deprecated, removed in 5.0
degreesMinutes: number | null; // deprecated, removed in 5.0
}

Inline mode shape (ui.inline)

Inline configuration shape, defined inline on UIOptions (not a separately exported type):

index.ts
ui: {
inline?: {
enabled: boolean;
container?: string | HTMLElement; // required when enabled is true
containerId?: string; // deprecated, use container
showButtons?: boolean;
autoUpdate?: boolean;
embedded?: boolean; // part of a host component, default false
showTitle?: boolean; // default true, new in 4.7.0
};
}

TimeOfDay

The argument of clock.isTimeDisabled. hour is always 0 to 23, in both clock types. seconds is 0 unless clock.showSeconds is on.

index.ts
import type { TimeOfDay } from 'timepicker-ui';
interface TimeOfDay {
hour: number;
minutes: number;
seconds: number;
}
const isTimeDisabled = ({ hour }: TimeOfDay): boolean => hour < 9 || hour >= 17;

RangeTimeValue and RangeTimeState

What picker.getRange() returns. An end is null until it has a full time.

index.ts
import type { RangeTimeValue, RangeTimeState } from 'timepicker-ui';
interface RangeTimeValue {
hour: string;
minutes: string;
seconds?: string; // showSeconds
type?: string; // 'AM' or 'PM' (12h mode)
}
interface RangeTimeState {
from: RangeTimeValue | null;
to: RangeTimeValue | null;
}
const range: RangeTimeState | null = picker.getRange();

TimepickerView

The two views of the picker. ui.initialView, setView(), getView() and the switch:view payload use it. New in 4.7.0.

index.ts
import type { TimepickerView } from 'timepicker-ui';
type TimepickerView = 'clock' | 'keyboard';

RangeTimeInput and RangeCaptionInput

The arguments of setRange() and setRangeCaptions(). Leave an end out to keep it. null or '' clears a time or removes a caption. New in 4.7.0.

index.ts
import type { RangeTimeInput, RangeCaptionInput } from 'timepicker-ui';
interface RangeTimeInput {
from?: string | null; // setValue() format: '09:00', '9:00 AM'
to?: string | null;
}
interface RangeCaptionInput {
from?: string | null; // plain text under the tab label
to?: string | null;
}
picker.setRange({ from: '09:00' });
picker.setRangeCaptions({ from: 'Wed Oct 21', to: null });

RangeChangeEventData

The payload of range:change and callbacks.onRangeChange. New in 4.7.0.

index.ts
import type { RangeChangeEventData } from 'timepicker-ui';
interface RangeChangeEventData {
part: 'from' | 'to'; // the end that changed
from: RangeTimeValue | null; // both ends after the change
to: RangeTimeValue | null;
}

TimeValue, TimeFormatOptions and DisabledTimeCheckOptions

Types of the parseTime(), formatTime() and createDisabledTimeCheck() helpers. TimeValue is the shape of a time that getValue() and getRange() use. New in 4.7.0.

index.ts
import type {
TimeValue,
TimeFormatOptions,
DisabledTimeCheckOptions
} from 'timepicker-ui';
interface TimeValue {
hour: string;
minutes: string;
seconds?: string; // showSeconds
type?: string; // 'AM' or 'PM' (12h mode)
}
interface TimeFormatOptions {
clockType?: '12h' | '24h'; // default '12h'
showSeconds?: boolean; // default false
}
type DisabledTimeCheckOptions = Pick<
ClockOptions,
'type' | 'disabledTime' | 'isTimeDisabled' | 'showSeconds'
>;

TimepickerEventName

The names of the events the picker emits, as a union. on(), once() and off() are typed with it, and the handler gets the payload type from TimepickerEventMap. Internal events are not in the union. New in 4.7.0.

index.ts
import type { TimepickerEventName, TimepickerEventMap } from 'timepicker-ui';
function listen<K extends TimepickerEventName>(
picker: TimepickerUI,
name: K,
handler: (data: TimepickerEventMap[K]) => void
) {
return picker.on(name, handler);
}
listen(picker, 'range:change', (data) => console.log(data.part));

PluginManager and PluginTimeView

Types for code that builds on the plugin system. PluginManager.setTimeView is optional and new in 4.7.0. The core calls it on the range plugin before init() and hands it a PluginTimeView, a port to the clock or wheel. In the wheel modes, view.show(value) moves the wheel to that time without emitting update, select:* or wheel:scroll:* events. Both types are exported from 'timepicker-ui' and change in 5.0.0, with the rest of the plugin API.

index.ts
import type { PluginManager, PluginTimeView } from 'timepicker-ui';
interface PluginTimeView {
show(value: { hour: string; minutes: string; seconds?: string; type?: string }): void;
}
interface PluginManager {
init(): void;
destroy(): void;
attachPopover?(): void;
detachPopover?(): void;
scrollToValue?(hour: string, minute: string, type?: string, second?: string): void;
getSelection?(): { hour: string; minutes: string; seconds?: string; type?: string } | null;
setTimeView?(view: PluginTimeView): void; // new in 4.7.0
}

Timezone plugin exports

Exported from 'timepicker-ui/plugins/timezone', not from 'timepicker-ui'. DEFAULT_TIMEZONES is the built-in list of IDs. getTimezoneList(list?) returns one TimezoneInfo for each ID the browser knows, and the built-in list when you pass none. New in 4.7.0.

index.ts
import {
getTimezoneList,
DEFAULT_TIMEZONES,
type TimezoneInfo
} from 'timepicker-ui/plugins/timezone';
interface TimezoneInfo {
readonly id: string; // 'Asia/Tokyo'
readonly label: string; // 'Tokyo (+09:00)'
readonly offset: string; // '+09:00'
}
const DEFAULT_TIMEZONES: readonly string[];
function getTimezoneList(list?: readonly string[]): TimezoneInfo[];
const zones = getTimezoneList([...DEFAULT_TIMEZONES, 'Europe/Warsaw']);

Disabled time shape (clock.disabledTime)

Disabled time configuration shape, defined inline on ClockOptions. When ranges is set, the hours, minutes and seconds lists are ignored.

index.ts
clock: {
disabledTime?: {
hours?: Array<string | number>;
minutes?: Array<string | number>;
seconds?: Array<string | number>; // used with showSeconds
ranges?: string | string[]; // e.g. "10:00 AM - 12:00 PM", "10:00:30 AM - 10:05 AM"
interval?: string | string[]; // deprecated, use ranges
};
isTimeDisabled?: (time: TimeOfDay) => boolean; // union with disabledTime
}

Default time shape (clock.defaultTime)

Default time configuration shape, defined inline on ClockOptions. 'now' also writes the time to the input. The object form writes it only with updateInput: true.

index.ts
clock: {
defaultTime?:
| 'now'
| {
time?: Date | 'now';
updateInput?: boolean;
};
}

Inline Unions

#

ui.theme

Available theme names. The union is defined inline on UIOptions (the library does not export a separate Theme alias).

index.ts
theme?:
| 'basic'
| 'crane'
| 'crane-straight'
| 'm2'
| 'm3-green'
| 'dark'
| 'glassmorphic'
| 'pastel'
| 'ai'
| 'cyberpunk'
| 'blueprint'
| 'blueprint-dark';

clock.type

Clock format, defined inline on ClockOptions (no exported ClockType alias).

index.ts
type?: '12h' | '24h' | 'auto'; // 'auto' follows the browser locale

clock.incrementSeconds

Seconds step, defined inline on ClockOptions.

index.ts
incrementSeconds?: 1 | 5 | 10 | 15 | 20 | 30;

Deprecated Types and Fields

#

These are marked @deprecated in the type definitions and will be removed in 5.0. They still compile, so existing code keeps working until then.

Type or fieldNote
Option names renamed in 4.5.0, e.g. UIOptions.mobile, LabelsOptions.hourLabelUse the new names. The Options page lists every pair under Renamed in 4.5.0.
ClearBehaviorOptions and the clearBehavior groupUse ui.clearButton: { clearInput }.
SelectAMEventData, SelectPMEventData, 'select:am', 'select:pm'Use SelectPeriodEventData and 'select:period'.
CallbacksOptions.onSelectAM / onSelectPMUse onSelectPeriod.
TimepickerUI.update()Use setOptions(options).
OptionTypesUse TimepickerOptions.
HideEventData and the 'hide' eventNever emitted.
OpenEventData.degreesHours / degreesMinutesInternal clock-hand angles. Use hour and minutes.
getValue().degreesHours / degreesMinutesInternal clock-hand angles. Use hour and minutes.
ErrorEventData.rejectedHour / rejectedMinuteAlways undefined.
ClockOptions.currentTime.localesHas no effect. The library formats the value.
LabelsOptions.format24LabelHas no effect.
LabelsOptions.toggleLabelHas no effect. The view switch is labelled by switchToKeyboard and switchToClock.
LabelsOptions.timezoneSelectorLabelHas no effect. Use labels.timezone.
'range:get-disabled-time' and 'range:update-disabled' eventsNever emitted or read.

Usage Examples

#

Basic TypeScript Usage

index.ts
import { TimepickerUI } from 'timepicker-ui';
import type { TimepickerOptions, ConfirmEventData } from 'timepicker-ui';
const options: TimepickerOptions = {
ui: { theme: 'dark' },
clock: { type: '24h' },
callbacks: {
onConfirm: (data: ConfirmEventData) => {
console.log(`Time: ${data.hour}:${data.minutes}`);
}
}
};
const input = document.querySelector<HTMLInputElement>('#timepicker');
if (input) {
const picker = new TimepickerUI(input, options);
picker.create();
}

Typed Event Subscriptions

index.ts
import { TimepickerUI } from 'timepicker-ui';
const picker = new TimepickerUI('#timepicker', {
clock: { showSeconds: true }
});
picker.create();
// picker.on is typed against TimepickerEventMap -
// the handler payload type is inferred from the event name
picker.on('confirm', (data) => {
// data: ConfirmEventData
console.log(data.hour, data.minutes, data.seconds, data.type, data.autoCommit);
});
picker.on('select:second', (data) => {
// data: SelectSecondEventData
console.log(data.seconds);
});
picker.on('select:period', (data) => {
// data: SelectPeriodEventData
console.log(data.type); // 'AM' | 'PM'
});
picker.on('switch:face', (data) => {
// data: SwitchFaceEventData
console.log(data.face); // 'hours' | 'minutes' | 'seconds'
});
picker.on('update', (data) => {
// data: UpdateEventData
console.log(data.hour, data.minutes, data.seconds, data.type);
});
picker.on('error', (data) => {
// data: ErrorEventData
console.error(data.error, data.inputHour, data.inputMinute, data.inputSecond);
});
picker.once('open', (data) => {
// data: OpenEventData
console.log(data.hour, data.minutes, data.seconds);
});

Typed on() overloads

index.ts
import { TimepickerUI } from 'timepicker-ui';
const picker = new TimepickerUI('#timepicker', { range: { enabled: true } });
picker.create();
picker.on('range:change', (data) => {
// data: RangeChangeEventData
console.log(data.part, data.from, data.to);
});
picker.on('switch:view', (data) => {
// data: SwitchViewEventData
console.log(data.view); // 'clock' | 'keyboard'
});
// A name outside TimepickerEventName still compiles; data is unknown
picker.on('my:custom', (data) => console.log(data));

React with TypeScript

index.tsx
import { useEffect, useRef } from 'react';
import { TimepickerUI } from 'timepicker-ui';
import type { TimepickerOptions } from 'timepicker-ui';
interface TimePickerProps {
onTimeSelect?: (time: string) => void;
theme?: 'basic' | 'dark' | 'cyberpunk';
}
export function TimePicker({ onTimeSelect, theme = 'basic' }: TimePickerProps) {
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (!inputRef.current) return;
const options: TimepickerOptions = {
ui: { theme },
callbacks: {
onConfirm: (data) => {
if (onTimeSelect && data.hour && data.minutes) {
const time = `${data.hour}:${data.minutes}`;
onTimeSelect(time);
}
}
}
};
const picker = new TimepickerUI(inputRef.current, options);
picker.create();
return () => picker.destroy();
}, [theme, onTimeSelect]);
return <input ref={inputRef} type="text" placeholder="Select time" />;
}

Error Handling

index.ts
import type { ConfirmEventData, ErrorEventData } from 'timepicker-ui';
import { TimepickerUI } from 'timepicker-ui';
const picker = new TimepickerUI('#timepicker', {
callbacks: {
onError: (data: ErrorEventData) => {
console.error('Timepicker error:', data.error);
alert(`Invalid time format: ${data.error}`);
},
onConfirm: (data: ConfirmEventData) => {
console.log('Time confirmed:', `${data.hour}:${data.minutes}`);
}
}
});

Extending Types

index.ts
import type { TimepickerOptions, ConfirmEventData } from 'timepicker-ui';
import { TimepickerUI } from 'timepicker-ui';
// Extend options with custom properties
interface CustomTimepickerOptions extends TimepickerOptions {
analyticsEnabled?: boolean;
}
// Create wrapper with custom logic
class CustomTimepicker {
private picker: TimepickerUI;
private analyticsEnabled: boolean;
constructor(
input: HTMLInputElement,
options: CustomTimepickerOptions
) {
const { analyticsEnabled, ...pickerOptions } = options;
this.analyticsEnabled = analyticsEnabled ?? false;
const finalOptions: TimepickerOptions = {
...pickerOptions,
callbacks: {
...pickerOptions.callbacks,
onConfirm: (data: ConfirmEventData) => {
if (this.analyticsEnabled) {
this.trackEvent('time_confirmed', data);
}
pickerOptions.callbacks?.onConfirm?.(data);
}
}
};
this.picker = new TimepickerUI(input, finalOptions);
}
private trackEvent(event: string, data: ConfirmEventData) {
console.log('Analytics:', event, data);
}
create() {
this.picker.create();
}
destroy() {
this.picker.destroy();
}
}

IntelliSense Support

All options and methods have full IntelliSense support in VS Code and other TypeScript-aware editors. Hover over any property to see its documentation.
Esc