mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 05:06:55 +04:00
Fix Datepicker getting stuck after the plugin throws in show() or hide() (#3255)
This commit is contained in:
1 parent
5aaa774470
commit
a1b46ae15e
4 files changed
+58
-14
No files matched your search
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tabler/core": patch
|
||||
---
|
||||
|
||||
Fixed `Datepicker` getting stuck closed after the calendar plugin throws in `show()` or `hide()`.
|
||||
+19
-12
@@ -245,18 +245,22 @@ class Datepicker extends BaseComponent {
|
||||
|
||||
this._isShowing = true
|
||||
this._skipPluginShow = false
|
||||
this._calendar.show()
|
||||
|
||||
// The first show builds the popup and opens it a tick later
|
||||
if (!this._isShown) {
|
||||
await new Promise<void>((resolve) => {
|
||||
this._resolveShown = resolve
|
||||
afterPluginTimers(resolve)
|
||||
})
|
||||
// Reset even if the plugin throws, or every later `show()` returns early
|
||||
try {
|
||||
this._calendar.show()
|
||||
|
||||
// The first show builds the popup and opens it a tick later
|
||||
if (!this._isShown) {
|
||||
await new Promise<void>((resolve) => {
|
||||
this._resolveShown = resolve
|
||||
afterPluginTimers(resolve)
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
this._resolveShown = null
|
||||
this._isShowing = false
|
||||
}
|
||||
|
||||
this._resolveShown = null
|
||||
this._isShowing = false
|
||||
}
|
||||
|
||||
// `async` like `show()`, so a plugin error reaches the caller as a rejection
|
||||
@@ -283,8 +287,11 @@ class Datepicker extends BaseComponent {
|
||||
})
|
||||
|
||||
this._isHiding = true
|
||||
this._calendar.hide()
|
||||
this._isHiding = false
|
||||
try {
|
||||
this._calendar.hide()
|
||||
} finally {
|
||||
this._isHiding = false
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -235,6 +235,38 @@ describe('Datepicker', () => {
|
||||
|
||||
expect(instance._isShown).toBe(false)
|
||||
})
|
||||
|
||||
it('should show again after the plugin throws while showing', async () => {
|
||||
fixtureEl.innerHTML = '<input type="text" data-bs-toggle="datepicker">'
|
||||
|
||||
const instance = new Datepicker(input())
|
||||
const pluginShow = vi.spyOn(instance.calendar!, 'show').mockImplementationOnce(() => {
|
||||
throw new Error('plugin failed')
|
||||
})
|
||||
|
||||
await expect(instance.show()).rejects.toThrow('plugin failed')
|
||||
expect(instance._isShowing).toBe(false)
|
||||
|
||||
await instance.show()
|
||||
expect(pluginShow).toHaveBeenCalledTimes(2)
|
||||
expect(instance._isShown).toBe(true)
|
||||
})
|
||||
|
||||
it('should hide again after the plugin throws while hiding', async () => {
|
||||
fixtureEl.innerHTML = '<input type="text" data-bs-toggle="datepicker">'
|
||||
|
||||
const instance = new Datepicker(input())
|
||||
await instance.show()
|
||||
vi.spyOn(instance.calendar!, 'hide').mockImplementationOnce(() => {
|
||||
throw new Error('plugin failed')
|
||||
})
|
||||
|
||||
await expect(instance.hide()).rejects.toThrow('plugin failed')
|
||||
expect(instance._isHiding).toBe(false)
|
||||
|
||||
await instance.hide()
|
||||
expect(instance._isShown).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('setSelectedDates', () => {
|
||||
|
||||
+2
-2
@@ -212,7 +212,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/tabler.js",
|
||||
"maxSize": "58 kB"
|
||||
"maxSize": "59 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/tabler.min.js",
|
||||
@@ -220,7 +220,7 @@
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/tabler.esm.js",
|
||||
"maxSize": "58 kB"
|
||||
"maxSize": "59 kB"
|
||||
},
|
||||
{
|
||||
"path": "./dist/js/tabler.esm.min.js",
|
||||
|
||||
Reference in new issue
Block a user