timepicker-ui
4.6.0GitHub
timepicker-ui
Project / Roadmap

Roadmap

Plans for timepicker-ui 5.0.0 and a list of what has shipped in 4.x.

No release date for 5.0.0

5.0.0 is planned, but it has no release date yet. 4.5.0 prepares for it: it adds clearer names for many options and deprecates the items in the table under “Removed in 5.0”. The other planned changes are announced on this page and in the changelog. To suggest a change, open an issue on GitHub.

Planned for 5.0.0

#

5.0.0 is a major release with breaking changes. This section lists what is decided so far. Where a detail is not decided yet, it says so.

Planned, no release date

New plugin system

Today you register a plugin once, at startup:

index.ts
import { PluginRegistry } from "timepicker-ui";
import { RangePlugin } from "timepicker-ui/plugins/range";
PluginRegistry.register(RangePlugin);

In 5.0, plugins will be built and registered in a different way. The new API is not designed yet, so there is no code to show.

These exports from timepicker-ui will change: PluginRegistry, Plugin, PluginManager, PluginFactory, TemplateProvider, ClearHandler, CoreState and EventEmitter.

The built-in plugins stay: range, timezone and wheel. A migration guide ships with 5.0.

CSS class names

CSS class names keep the tp-ui- prefix. The part after the prefix is reworked to follow Material Design component naming.

Custom CSS that targets these classes will need updating. 5.0 ships a table of old and new names.

New picker style

5.0 adds a new picker style that you turn on with an option. It follows Material Design, like the default basic theme, and does not replace it.

Design preview: new style in 5.0

A static picture, not a working picker. The switches show or hide the range and time zone parts. The style is not in 4.5, and its final look and option name may change.

Desktop
Meeting time
Time rangeSelect time
From
:
To
:
1 h 30 min
Hours · From24 h
Time zone
Mobile
9:41
New meeting
Time rangeSelect time
From
:
To
:
1 h 30 min
Hours · From24 h
Time zone

Light and dark mode

A new option, ui.colorScheme, takes 'auto', 'light' or 'dark' and defaults to 'auto'. The picker then matches the page: it checks the background behind the input when it opens, then the page's color-scheme, then the system setting. An inline picker follows the page when it switches modes.

Themes that come in a light and a dark version switch on their own: basic, the new style, and blueprint with blueprint-dark. Set 'light' or 'dark' to force one version, for example a dark picker on a light page. Themes with a single version ignore the option.

The dark version of basic follows the Material Design 3 dark color scheme. It replaces the dark theme, which is removed: use ui.colorScheme: 'dark' instead. If you prefer the current dark look, the 5.0 docs show how to bring it back with your own CSS.

More planned for 5.0

These are planned, but their options and details are not decided yet.

  • Forms. The picker works in a form like <input type="time">: it submits the time as HH:mm or HH:mm:ss whatever the display format, supports required and form reset, and fires input and change on the field, so form libraries pick up the value.
  • Minimum and maximum time. Limits such as min: 'now' for bookings, for the common cases that need clock.disabledTime today.
  • Theming from one color. Set one CSS variable to your brand color and the rest of the palette follows, computed in CSS. The library styles sit in a cascade layer, so your own CSS wins without raising specificity.
  • Smarter typing. In an editable input, entries such as 1430, 14.30, 2p or 2:30pm become a valid time when the field loses focus.
  • Locale from Intl. AM/PM names, digits and the hour format of a locale without shipping translations, and a right-to-left layout for languages such as Arabic and Hebrew.
  • Range. The duration shown between the two times, ranges that cross midnight marked with +1 day, and a minimum and maximum length.
  • Quick picks. Buttons such as “Now”, “+15 min” or times you choose.
  • Web component. A <timepicker-ui> element for frameworks that have no wrapper.
  • Desktop popover and mobile sheet. On desktop the picker opens under the field, and on phones it opens as a bottom sheet that you swipe down to close.

Quick picks and the web component come as separate imports, so they add nothing to your bundle when you do not use them.

Removed in 5.0

Each item below is deprecated in 4.5.0 and removed in 5.0.

Deprecated in 4.5.0What to do
Old names of the options renamed in 4.5.0, for example ui.mobile and labels.hourLabelUse the new names. The Renamed in 4.5.0 table lists every pair.
select:am and select:pm events, callbacks.onSelectAM and callbacks.onSelectPMUse select:period or callbacks.onSelectPeriod. The payload is { type: 'AM' | 'PM' }.
update({ options, create }, callback)Use setOptions(options). If you passed create: true, call picker.create() after it. Code from the callback can run on the next line.
OptionTypes typeUse TimepickerOptions.
clock.currentTime.localesRemove it. It has no effect since 4.5.0, because the library formats the value itself.
getValue().degreesHours, getValue().degreesMinutesStop reading them. They are internal clock angles.
labels.toggleLabelRemove it.
labels.format24LabelRemove it. It has no effect.
labels.timezoneSelectorLabelIt has no effect. Use labels.timezone.
focusInputAfterCloseModal (legacy option)Use behavior.returnFocus. It defaults to false; 5.0 makes true the default.
hide event and HideEventDataRemove listeners for it. The picker never emits hide.
range:get-disabled-time and range:update-disabled eventsRemove listeners for them. The picker never emits them.
ErrorEventData.rejectedHour, ErrorEventData.rejectedMinuteStop reading them. They are always undefined.

Also removed: APIs that do nothing or mislead

  • Internal events in the public TimepickerEventMap: range:minute:commit and animation:*. The map also loses its catch-all index signature, so on('typo') becomes a type error.
  • behavior.delayHandler. It only delays closing the picker. It never debounced the buttons.
  • TimepickerUI.isAvailable(). It does the same as document.querySelector(...) !== null.
  • The undocumented getters hour, minutes, okButton, cancelButton and clockHand on the picker instance. They return internal DOM elements.
  • The callback arguments of open(cb) and destroy(), in both forms: destroy(cb) and destroy({ callback }). Run that code after the call, or use picker.once('open', ...).
  • RangeManager, TimezoneManager and WheelManager, exported from the plugin entry points. You cannot get an instance of them from a picker today, and the new plugin API replaces them.

Options and events

  • The options renamed in 4.5.0 lose their old names, together with the clearBehavior group. The Renamed in 4.5.0 table lists every pair.
  • select:hour, select:minute and select:second fire once when a value of their unit is picked, in every mode: on dial release, on an arrow key, on a typed value, or when a wheel column stops. Today, in clock mode, they fire when a field is activated, so picking an hour on the dial fires select:minute. In 5.0, activating a field fires only switch:face, which 4.5.0 already emits.
  • ui.footer replaces ui.inline.showButtons and wheel.hideFooter. Unset, the OK, Cancel and Clear buttons show except in inline mode. false hides them in every mode, and true shows them in inline mode too.
  • behavior.commitOnChange replaces ui.inline.autoUpdate and wheel.commitOnScroll. Each picked value is written to the input and confirm fires with autoCommit: true, and the picker stays open. Unlike inline.autoUpdate today, it emits confirm.
  • behavior.ignoreOutsideClick replaces wheel.ignoreOutsideClick and works in every mode: a click outside the picker does not close it. Escape, Cancel and OK still do.
  • behavior.returnFocus defaults to true: on close, focus goes back to the input or the data-open element that opened the picker.
  • ui.cssClass is applied to one element instead of two.

Package and CSS

  • The plugins no longer ship UMD builds. The UMD core never exposed PluginRegistry, so a plugin loaded from a <script> tag could not be registered. The core UMD build stays.
  • About 50 CSS custom properties that no rule reads are removed, for example --tp-tertiary-container, --tp-on-tertiary-container, --tp-radius, --tp-hover-bg and 18 of the 34 --tp-size-* tokens. Setting them today changes nothing. 5.0 lists them all.
  • The ./plugins/* wildcard in the exports field of package.json is removed. The explicit ./plugins/range, ./plugins/timezone and ./plugins/wheel entries stay, so the plugin imports shown in these docs keep working.
  • The crane-straight theme becomes a variant of crane with square corners. The name of the option that turns it on is not decided yet.
  • ui.keyboardIcon and ui.clockIcon take an element or a factory function instead of an HTML string.

Smaller bundle

5.0 will remove code that is no longer needed: the backward-compatibility paths for the deprecated items above, and dead code. The goal is less JavaScript to download and parse, for the core and for each plugin.

4.5.0 already removes internal dead code that has no effect on the public API or markup. 5.0 removes the rest, together with the items above.

No target size is set yet. Current sizes are on the Bundle analysis page.

What you can do now

#

The steps you can take on 4.5.0 to prepare for 5.0 are in the Migration Guide v4 to v5.

If you use or write plugins, open an issue on GitHub and describe the use cases you want the new plugin API to cover.

Released in 4.x

#

Shipped

Plugin system Completed
Optional plugins for range selection, timezones and the wheel UI, registered with PluginRegistry.register(). Since 4.3.0, a plugin you do not import is left out of your bundle.
Range plugin Completed
Select a start and an end time. range.minDuration and range.maxDuration set the allowed length in minutes.
Timezone plugin Completed
A timezone dropdown. timezone.list sets the zones it shows.
Wheel plugin Completed
Added in 4.2.0. A scroll-wheel UI instead of the clock face, set with ui.mode: 'wheel' or 'compact-wheel'.
Manager architecture Completed
Internally, the picker is split into eight managers: AnimationManager, ModalManager, ConfigManager, ThemeManager, ValidationManager, EventManager, ClockManager and ClearButtonManager.
TypeScript types Completed
The library is compiled with TypeScript strict mode and exports types for the option groups and event payloads.
SSR safety Completed
Safe to import during server-side rendering. Code that needs the browser checks for window or document first. Create the picker on the client, for example in useEffect.
Blueprint themes Completed
Added in 4.4.0: blueprint and blueprint-dark. There are now 12 built-in themes.
Event API Completed
picker.on(), picker.once() and picker.off() subscribe to events. They replaced the timepicker:* DOM events, which 4.0.0 removed.
Keyboard navigation Completed
Up and Down arrows, Home, End, Page Up and Page Down change the hour and minute. Tab and Shift+Tab stay inside the open picker (behavior.focusTrap, on by default). Enter on the input opens the picker and Escape closes it.
Time steps Completed
clock.incrementMinutes and clock.incrementHours set the step between selectable values.
Clock format from the locale Completed
Added in 4.5.0: clock.type: 'auto' picks 12h or 24h from the browser locale.
Clearer option names Completed
Added in 4.5.0, for example ui.initialView for ui.mobile. The old names work until 5.0, and the options page lists every pair.

Ideas, not scheduled

#

These ideas are not committed to 5.0 or to any other release.

Customization

Custom clock faces Idea
Custom clock face designs and behavior.
Animation presets Idea
Predefined animations, such as bounce, slide and fade, with custom timing.

How releases work

#

Releases happen when they are ready. There is no fixed schedule. Version numbers follow semantic versioning.

Patch releases
4.x.y
Bug fixes.
Minor releases
4.5.0
New features without breaking changes. The changelog lists the changes in 4.5.0.
Major releases
5.0.0
Breaking changes. 5.0.0 ships with a migration guide.

Contribute

To work on the code, read the contributing guide.
Esc