npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wts-timepicker

v19.0.0

Published

Dependency-free, accessible, framework-agnostic clock-face time picker and Web Component.

Downloads

122

Readme

wts-timepicker

A dependency-free, accessible clock-face time picker for JavaScript, TypeScript, Angular, React, Vue, Svelte, and plain HTML.

The package provides two APIs:

  • WtsTimepicker, an imperative DOM controller; and
  • <wts-timepicker>, a form-associated Web Component.

It has no runtime dependencies and importing either entry point is safe during server-side rendering.

Install

npm install wts-timepicker

JavaScript and TypeScript

<input id="meeting-time" value="02:45 pm">
<div id="picker"></div>
import { WtsTimepicker } from 'wts-timepicker';

const picker = new WtsTimepicker('#picker', {
  trigger: '#meeting-time',
  value: '02:45 pm',
  format: 12,
  minutesGap: 5,
  appearance: 'dialog',
  onChange(value) {
    console.log(value);
  },
});

picker.open();
picker.setValue('04:30 pm');
picker.destroy();

The default styles are injected automatically. To manage styles yourself:

import { WtsTimepicker } from 'wts-timepicker';
import 'wts-timepicker/styles.css';

new WtsTimepicker('#picker', { injectStyles: false });

Web Component

Import the registration entry once:

import 'wts-timepicker/element';

Then use the element in HTML:

<form>
  <wts-timepicker
    name="meetingTime"
    required
    value="02:45 pm"
    min="09:00"
    max="17:00"
    step="15"
    format="12"
    minutes-gap="5"
    appearance="inline"
    auto-close="false"
  ></wts-timepicker>
  <button>Submit</button>
</form>

Omit value, or set it to an empty string, when the form should start unselected. The element then exposes native-style form, labels, validity, validationMessage, willValidate, checkValidity(), and reportValidity() APIs. A required empty picker is invalid until a time is committed. The read-only clockFace type does not submit a form value. Form submission always uses the stable 24-hour HH:mm representation, while value retains the configured package format and displayValue contains the locale-aware visible text.

const picker = document.querySelector('wts-timepicker');

picker.value;          // "02:45 pm"
picker.canonicalValue; // "14:45"
picker.formValue;      // "14:45"
picker.displayValue;   // locale-aware
picker.valueAsTime;    // { hour: 14, minute: 45, second: 0 }
picker.valueAsMinutes; // 885

When min is later than max, the allowed range crosses midnight. For example, min="22:00" max="02:00" allows late-night and early-morning times. step is expressed in minutes and is anchored to min, or midnight when no minimum is supplied.

Custom dropdown mode

Use picker-mode="dropdown" for a compact custom dropdown UI instead of the clock dial. It uses accessible combobox/listbox semantics rather than native <select> elements, supports full keyboard navigation, and shares the same constraints, localization, events, form value, and validation behavior.

<wts-timepicker
  picker-mode="dropdown"
  appearance="inline"
  value="02:45 pm"
  min="09:00"
  max="17:00"
  step="15"
></wts-timepicker>

For dialog presentation:

<button id="open-picker" type="button">Choose time</button>
<wts-timepicker id="picker" value="02:45 pm"></wts-timepicker>

<script type="module">
  import 'wts-timepicker/element';

  const picker = document.querySelector('#picker');
  document
    .querySelector('#open-picker')
    .addEventListener('click', () => picker.showPicker());

  picker.addEventListener('change', (event) => {
    console.log(event.detail.value);
  });
</script>

Framework use

Web Components work directly in Vue and Svelte. React users should set element properties through a ref when a non-string value is needed. Angular users can add CUSTOM_ELEMENTS_SCHEMA to the consuming component or module and import wts-timepicker/element once.

The imperative controller is also available in every framework and is useful when the framework should own the surrounding input.

Options

| Option | Default | Description | | --- | --- | --- | | value | current local time (controller), empty (element) | A Date, formatted time string, or empty string | | min | none | Earliest selectable time; accepts configured or canonical format | | max | none | Latest selectable time; supports ranges crossing midnight | | step | 1 | Selectable minute interval from 1 through 720 | | format | 12 | 12 or 24 hour output | | minutesGap | 5 | Visible minute-label interval, from 1 to 30 | | locale | none | Locale for visible time, numerals, and day periods | | labels | English labels | Accessible hour, minute, selectHour, selectMinute, period, and currentTime labels | | type | timepicker | Interactive timepicker or live clockFace | | pickerMode | clock | Interactive clock dial or custom dropdown | | appearance | dialog | Modal dialog or inline presentation | | headerEnabled | true | Displays hour and minute fields | | footerEnabled | true | Displays Cancel and Apply | | positionX | left | left or right inline alignment | | positionY | auto | auto, top, or bottom inline placement | | closeOnEscape | true | Cancels the picker on Escape | | autoClose | true | Commits after a minute is selected | | disabled | false | Disables interaction | | readOnly | false | Prevents edits | | injectStyles | true | Injects the bundled styles | | trigger | null | Element or selector that opens the picker |

Callbacks are available as onInput, onChange, onOpen, and onClose.

The Web Component exposes labels through attributes such as hour-label, minute-label, select-hour-label, select-minute-label, period-label, and current-time-label.

<wts-timepicker
  appearance="inline"
  format="24"
  locale="de-DE"
  hour-label="Stunde"
  minute-label="Minute"
  select-hour-label="Stunde auswählen"
  select-minute-label="Minute auswählen"
></wts-timepicker>

Controller methods

picker.open();
picker.close();       // cancel
picker.close(true);   // commit
picker.apply();
picker.cancel();
picker.setValue('14:30');
picker.setOptions({ format: 24 });
picker.destroy();

The current committed values are available through picker.value and picker.time.

Clock digits use a single keyboard tab stop. Use the arrow keys to move and select, or Home and End to jump to the first or last value. Escape cancels an open picker and returns focus to its trigger.

Events

Both APIs emit:

  • input when the draft selection changes;
  • change when a value is committed;
  • wts-timepicker-open when the picker opens; and
  • wts-timepicker-close when it closes.

input and change are composed CustomEvent instances:

pickerElement.addEventListener('change', (event) => {
  console.log(event.detail.value);
  console.log(event.detail.canonicalValue); // "21:15"
  console.log(event.detail.displayValue);   // locale-aware
  console.log(event.detail.time); // { hour, minute, second }
});

Styling

The main CSS custom properties are:

wts-timepicker {
  --wts-timepicker-accent: #6d28d9;
  --wts-timepicker-accent-contrast: #fff;
  --wts-timepicker-background: #fff;
  --wts-timepicker-border: #6d28d9;
  --wts-timepicker-color: #202124;
  --wts-timepicker-size: 300px;
}

Web Component internals can be customized without reaching into its Shadow DOM:

wts-timepicker::part(panel) {
  border-radius: 20px;
}

wts-timepicker::part(apply-button) {
  font-weight: 800;
}

wts-timepicker::part(digit) {
  font-variant-numeric: tabular-nums;
}

Available parts include root, overlay, panel, header, fields, hour-field, minute-field, period, period-button, face, digit, hour-digit, minute-digit, hand, footer, cancel-button, apply-button, error, dropdown, dropdown-field, dropdown-trigger, dropdown-menu, and dropdown-option.

Pure time utilities

Parsing, formatting, clock-item generation, and hand geometry can be used without constructing DOM:

import {
  clockHandAngles,
  formatTime,
  parseTime,
} from 'wts-timepicker';

const time = parseTime('09:15 pm', 12);
if (time) {
  console.log(formatTime(time, 24)); // 21:15
  console.log(clockHandAngles(time));
}

Migration

Version 19 replaces the Angular component and directive with portable APIs. See MIGRATION.md for the Angular migration.