Skip to content
GuideBeta

Migration Guide v4 to v5

What 5.0 removes and changes, and what you can update on 4.5.0 today.

This guide is a draft

5.0 is not fully designed yet. This guide lists what is decided so far and changes as 5.0 takes shape. The final version ships with 5.0.

The plan for 5.0 is on the roadmap. If something you use is missing here, open an issue on GitHub.

Still on 3.x?

Upgrade to 4.x first with the Migration Guide v3 to v4. It already uses the option names from 4.5.0.

What you can do now

Each step works on 4.5.0, so you can make these changes before 5.0 is released.

  1. Upgrade to 4.5.0. Your editor shows deprecated APIs with a strikethrough. Replace each one using the Removed in 5.0 table.
  2. Move to the option names from the Renamed options table, and replace update() with setOptions().
  3. If you use callbacks.onSelectHour or select:hour to notice that the clock face changed, use switch:face or callbacks.onSwitchFace instead.
  4. Set behavior.returnFocus: true, so the 5.0 default does not change how your page behaves. See Changed defaults.
  5. Code you pass as a callback to open() or destroy() can run on the line after the call instead. 5.0 removes these callback arguments.
  6. Keep custom CSS that targets tp-ui-* classes in one place, so the rename touches as few files as possible.

Renamed options

These options got clearer names in 4.5.0. The old names still work and are removed in 5.0. When both names are set, the new one wins. picker.options keeps returning the old names until 5.0.

Names from 4.0 to 4.4

index.tstypescript
const picker = new TimepickerUI('#time', {
clock: { currentTime: true, smoothHourSnap: false },
ui: { mobile: true, enableSwitchIcon: true },
behavior: { focusInputAfterClose: true },
callbacks: {
onSelectAM: () => console.log('AM'),
onSelectPM: () => console.log('PM'),
},
});
picker.create();
picker.update({ options: { ui: { theme: 'dark' } } });

Names from 4.5.0

index.tstypescript
const picker = new TimepickerUI('#time', {
clock: { defaultTime: 'now', discreteHourJump: true },
ui: { initialView: 'keyboard', viewSwitch: true },
behavior: { returnFocus: true },
callbacks: {
onSelectPeriod: ({ type }) => console.log(type),
},
});
picker.create();
picker.setOptions({ ui: { theme: 'dark' } });
Old nameNew nameNote
clock.currentTime: trueclock.defaultTime: 'now'Shows the current time and writes it to the input.
clock.currentTime: { time, updateInput }clock.defaultTime: { time, updateInput }time is a Date or 'now'. locales has no effect and has no new name.
clock.currentTime.preventClockType: trueclock.type: 'auto'12h or 24h from the browser locale, with or without defaultTime.
clock.disabledTime.intervalclock.disabledTime.ranges
clock.smoothHourSnap: falseclock.discreteHourJump: trueInverted. Smooth movement stays the default.
ui.mobile: trueui.initialView: 'keyboard'
ui.enableSwitchIconui.viewSwitch
ui.enableScrollbarui.allowPageScroll
ui.appendModalSelectorui.appendToAlso accepts an element.
ui.iconTemplateui.keyboardIcon
ui.iconTemplateMobileui.clockIcon
ui.inline.containerId: 'x'ui.inline.container: '#x'A selector or an element.
clearBehavior.clearInputui.clearButton: { clearInput }The object form also shows the Clear button.
behavior.focusInputAfterClosebehavior.returnFocus5.0 makes true the default.
timezone.whitelisttimezone.list
timezone.labellabels.timezone
range.fromLabellabels.rangeFrom
range.toLabellabels.rangeTo
labels.timelabels.clockTitle
labels.mobileTimelabels.keyboardTitle
labels.mobileHour, labels.hourLabel, labels.announceHourlabels.hourOne key for the caption, the accessible name and the announcement. An old key set next to it still wins for its own use.
labels.mobileMinute, labels.minuteLabel, labels.announceMinutelabels.minuteSame as labels.hour.
labels.clockLabellabels.clock
labels.periodLabellabels.period
labels.timeLabellabels.timeFields
labels.rangeSelectionLabellabels.range
labels.switchToKeyboardLabellabels.switchToKeyboard
labels.switchToClockLabellabels.switchToClock
callbacks.onSelectAM, callbacks.onSelectPMcallbacks.onSelectPeriodReceives { type: 'AM' | 'PM' }. The select:am and select:pm events become select:period.
picker.update({ options })picker.setOptions(options)Method. See Methods.

Removed in 5.0

Each item below is deprecated in 4.5.0 and removed in 5.0. Replace or remove it now.

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.

Changed defaults

In 5.0, behavior.returnFocus defaults to true: when the picker closes, focus goes back to the input, or to the data-open element that opened the picker. In 4.5.0 the default is false.

To opt in now, set it to true. In 4.5.0 this returns focus to the input when the picker closes.

index.tstypescript
const picker = new TimepickerUI('#time', {
behavior: { returnFocus: true },
});
picker.create();

If you set behavior.returnFocus: false yourself, the new default does not affect you.

The new ui.colorScheme option defaults to 'auto', so the picker matches a light or dark page. On a dark page, basic shows its dark version. To keep the light picker everywhere, set ui.colorScheme: 'light'. The roadmap describes how the mode is detected.

Other changes in 5.0

Changes the 5.0 plan already describes. Where a detail is not decided yet, it says so.

Events and options

  • 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. In 4.5.0, in clock mode, they fire when a field is activated. To react to the clock face changing, listen to switch:face, which 4.5.0 already emits:
    index.tstypescript
    picker.on('switch:face', ({ face }) => {
    console.log(face); // 'hours', 'minutes' or 'seconds'
    });
  • 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. If you use ui.inline.autoUpdate, check your confirm handlers: in 4.5.0 it does not emit confirm.
  • behavior.ignoreOutsideClick replaces wheel.ignoreOutsideClick and works in every mode. Escape, Cancel and OK still close the picker.
  • ui.cssClass is applied to one element instead of two. Check the CSS that uses your class.
  • TimepickerEventMap loses the internal events range:minute:commit and animation:*, and its catch-all index signature, so on('typo') becomes a type error. Remove listeners for those events.

Also removed

Your editor does not flag these in 4.5.0.

  • behavior.delayHandler. It only delays closing the picker. Remove it from your options; 4.5.0 already defaults it to 0.
  • TimepickerUI.isAvailable(). Use document.querySelector(...) !== null.
  • The undocumented getters hour, minutes, okButton, cancelButton and clockHand on the picker instance. They return internal DOM elements. Read the time with getValue().
  • 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. The new plugin API replaces them.

Plugins

  • Plugins will be built and registered in a different way. The new API is not designed yet. Details will be added here before 5.0. These exports from timepicker-ui change: PluginRegistry, Plugin, PluginManager, PluginFactory, TemplateProvider, ClearHandler, CoreState and EventEmitter. The built-in plugins stay: range, timezone and wheel.
  • Import plugins from timepicker-ui/plugins/range, timepicker-ui/plugins/timezone and timepicker-ui/plugins/wheel. The ./plugins/* wildcard in the exports field of package.json is removed. These three entries stay.
  • 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.

CSS and themes

  • CSS class names keep the tp-ui- prefix. The part after it follows Material Design component names. Custom CSS that targets these classes needs updating. The table of old and new names will be added here before 5.0.
  • 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 in 4.5.0 changes nothing, so you can delete them. 5.0 lists them all.
  • 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.
  • The dark theme is removed. Its place is taken by the dark version of basic, which follows the Material Design 3 dark color scheme. Replace ui.theme: 'dark' with ui.colorScheme: 'dark'. To keep the current dark look, override the styles with your own CSS. The CSS needed will be added here before 5.0.
  • 5.0 adds an optional new picker style that does not replace the basic theme. The roadmap has a design preview.
  • ui.keyboardIcon and ui.clockIcon take an element or a factory function instead of an HTML string. Details will be added here before 5.0.

For the reasons behind these changes, see the roadmap.