mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Fix Datepicker throwing on Vanilla Calendar Pro 3.4 by registering its extensions (#3231)
This commit is contained in:
1 parent
dee65f2f5c
commit
4f471ddccf
6 files changed
+66
-8
No files matched your search
@@ -5,7 +5,7 @@
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import type { Calendar, Options, Range } from 'vanilla-calendar-pro'
|
||||
import type { Calendar, CalendarExtension, Options, Range } from 'vanilla-calendar-pro'
|
||||
import BaseComponent from './bootstrap/base-component'
|
||||
import EventHandler from './bootstrap/dom/event-handler'
|
||||
import SelectorEngine from './bootstrap/dom/selector-engine'
|
||||
@@ -40,6 +40,13 @@ const HIDE_DELAY = 100 // ms delay before hiding after selection
|
||||
|
||||
const DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/
|
||||
|
||||
// Vanilla Calendar Pro 3.4 moved several months, the time picker, week
|
||||
// numbers, popups and animation into extensions that must be registered when
|
||||
// the calendar is created, or its constructor throws. The library is loaded
|
||||
// as a whole on `window`, so every extension it exports is registered;
|
||||
// 3.3 exports none and gets no `extensions` option.
|
||||
const EXTENSION_NAMES = ['annotations', 'months', 'motion', 'time', 'weeks'] as const
|
||||
|
||||
// The public API is typed with local copies of the Vanilla Calendar Pro types.
|
||||
// `vanilla-calendar-pro` is an optional peer dependency, so the published
|
||||
// `dist/types` must not import it: a project that never loads the datepicker
|
||||
@@ -555,14 +562,35 @@ class Datepicker extends BaseComponent {
|
||||
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
||||
}
|
||||
|
||||
// The extensions the loaded library exports, after the ones the caller
|
||||
// registered in `vcpOptions` themselves.
|
||||
/** @internal */
|
||||
_calendarExtensions(own: readonly CalendarExtension[] = []): CalendarExtension[] {
|
||||
const library = window.VanillaCalendarPro as Record<string, unknown> | undefined
|
||||
const extensions = [...own]
|
||||
|
||||
for (const name of EXTENSION_NAMES) {
|
||||
const extension = library?.[name] as CalendarExtension | undefined
|
||||
if (extension && typeof extension === 'object' && !extensions.includes(extension)) {
|
||||
extensions.push(extension)
|
||||
}
|
||||
}
|
||||
|
||||
return extensions
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_buildCalendarOptions(): Options {
|
||||
// The plugin uses 'system' for auto-detection, Bootstrap and Tabler use 'auto'
|
||||
const theme = this._getEffectiveTheme()
|
||||
const vcpTheme = !theme || theme === 'auto' ? 'system' : theme
|
||||
|
||||
const vcpOptions = this._config.vcpOptions as Options
|
||||
const extensions = this._calendarExtensions(vcpOptions.extensions)
|
||||
|
||||
const calendarOptions: Options = {
|
||||
...this._config.vcpOptions,
|
||||
...vcpOptions,
|
||||
...(extensions.length > 0 ? { extensions } : {}),
|
||||
inputMode: !this._isInline,
|
||||
positionToInput: this._config.placement,
|
||||
firstWeekday: this._config.firstWeekday,
|
||||
|
||||
@@ -58,6 +58,28 @@ describe('Datepicker', () => {
|
||||
expect(instance._isInput).toBe(true)
|
||||
})
|
||||
|
||||
it('should register the extensions the library exports', () => {
|
||||
fixtureEl.innerHTML = '<input type="text" data-bs-toggle="datepicker" data-bs-display-months-count="2">'
|
||||
|
||||
const instance = new Datepicker(input())
|
||||
|
||||
const calendar = instance.calendar as VanillaCalendarPro.Calendar
|
||||
expect(calendar.extensions).toContain(VanillaCalendarPro.months)
|
||||
expect(calendar.extensions).toContain(VanillaCalendarPro.time)
|
||||
expect(calendar.type).toBe('multiple')
|
||||
expect(calendar.displayMonthsCount).toBe(2)
|
||||
})
|
||||
|
||||
it('should keep the extensions passed in vcpOptions once', () => {
|
||||
fixtureEl.innerHTML = '<input type="text" data-bs-toggle="datepicker">'
|
||||
|
||||
const instance = new Datepicker(input(), { vcpOptions: { extensions: [VanillaCalendarPro.months] } })
|
||||
|
||||
const extensions = (instance.calendar as VanillaCalendarPro.Calendar).extensions
|
||||
expect(extensions.filter((extension) => extension === VanillaCalendarPro.months)).toHaveLength(1)
|
||||
expect(extensions).toContain(VanillaCalendarPro.motion)
|
||||
})
|
||||
|
||||
it('should stay inert without the plugin', () => {
|
||||
delete window.VanillaCalendarPro
|
||||
fixtureEl.innerHTML = '<input type="text" data-bs-toggle="datepicker">'
|
||||
|
||||
+1
-1
@@ -287,7 +287,7 @@
|
||||
"tom-select": "^2.6.2",
|
||||
"typed.js": "^3.0.0",
|
||||
"typescript": "^7.0.2",
|
||||
"vanilla-calendar-pro": "^3.3.2",
|
||||
"vanilla-calendar-pro": "^3.4.0",
|
||||
"vitest": "4.1.11"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user