Skip to content

Commit c36cf45

Browse files
authored
fix: calling open() method multiple times should keep drop (re)open (#33)
* fix: calling open() method multiple times should keep drop (re)open - in the original ms-select, the body click was being triggered prior to the open() method but that is inversed in our new lib with vanilla JS, so in order to have the same lifecycle as the original, we can simply add a single CPU cycle delay. This delay arg could also be used by the users for other reasons
1 parent ee8127d commit c36cf45

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

lib/src/MultipleSelectInstance.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -347,11 +347,11 @@ export class MultipleSelectInstance {
347347
this.update(true);
348348

349349
if (this.options.isOpen) {
350-
setTimeout(() => this.open(), 10);
350+
this.open(10);
351351
}
352352

353353
if (this.options.openOnHover && this.parentElm) {
354-
this._bindEventService.bind(this.parentElm, 'mouseover', () => this.open());
354+
this._bindEventService.bind(this.parentElm, 'mouseover', () => this.open(null));
355355
this._bindEventService.bind(this.parentElm, 'mouseout', () => this.close());
356356
}
357357
}
@@ -792,12 +792,26 @@ export class MultipleSelectInstance {
792792
}) as EventListener);
793793
}
794794

795-
open() {
795+
/**
796+
* Open the drop method, user could optionally provide a delay in ms to open the drop.
797+
* The default delay is 0ms (which is 1 CPU cycle) when nothing is provided, to avoid a delay we can pass `-1` or `null`
798+
* @param {number} [openDelay=0] - provide an optional delay, defaults to 0
799+
*/
800+
open(openDelay: number | null = 0) {
801+
if (openDelay !== null && openDelay >= 0) {
802+
let timer: NodeJS.Timeout | undefined;
803+
clearTimeout(timer);
804+
timer = setTimeout(() => this.openDrop(), openDelay);
805+
} else {
806+
this.openDrop();
807+
}
808+
}
809+
810+
protected openDrop() {
796811
if (this.choiceElm?.classList.contains('disabled')) {
797812
return;
798813
}
799-
// this.options.isOpen = true;
800-
setTimeout(() => (this.options.isOpen = true)); // TODO: original code doesn't require this delay
814+
this.options.isOpen = true;
801815
this.parentElm.classList.add('ms-parent-open');
802816
this.choiceElm?.querySelector('div')?.classList.add('open');
803817
this.dropElm.style.display = 'block';
@@ -827,8 +841,8 @@ export class MultipleSelectInstance {
827841
} else if (typeof this.options.container === 'string') {
828842
// prettier-ignore
829843
container = this.options.container === 'body'
830-
? document.body
831-
: document.querySelector(this.options.container) as HTMLElement;
844+
? document.body
845+
: document.querySelector(this.options.container) as HTMLElement;
832846
}
833847
container!.appendChild(this.dropElm);
834848
this.dropElm.style.top = `${offset?.top ?? 0}px`;

playwright/e2e/methods05.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { test, expect } from '@playwright/test';
2+
3+
test.describe('Methods 05 - open/close', () => {
4+
test('open & close drop dynamically', async ({ page }) => {
5+
await page.goto('#/methods05');
6+
await page.locator('.ms-parent').click();
7+
await expect(await page.locator('.ms-drop')).toBeVisible();
8+
9+
await page.getByRole('button', { name: 'Close' }).click();
10+
await expect(await page.locator('.ms-drop')).not.toBeVisible();
11+
12+
// clicking on Close multiple times should keep the drop closed regardless
13+
await page.getByRole('button', { name: 'Close' }).click();
14+
await expect(await page.locator('.ms-drop')).not.toBeVisible();
15+
16+
await page.getByRole('button', { name: 'Open' }).click();
17+
await expect(await page.locator('.ms-drop')).toBeVisible();
18+
19+
// clicking on Open multiple times should keep the drop open regardless
20+
await page.getByRole('button', { name: 'Open' }).click();
21+
await expect(await page.locator('.ms-drop')).toBeVisible();
22+
});
23+
});

0 commit comments

Comments
 (0)