Skip to content

Commit

Permalink
fix(select): close select on menu close
Browse files Browse the repository at this point in the history
There are some situations where the menu can close when the outer select
is still open and unaware.

For example, clicking the field will open the menu, then clicking it
again will close the menu **but not the select**.

This is because the menu observes outside clicks in order to close
itself. We don't currently observe those closes to update our own state
inside `md-select`, so the UI still shows as if it is open but without a
menu.

The fix here is to always reflect the state of the menu on `closed`.
  • Loading branch information
43081j committed Feb 26, 2024
1 parent ec0a8eb commit 76537b0
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
15 changes: 15 additions & 0 deletions select/harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export class SelectHarness extends Harness<Select> {
protected getField() {
return this.element.renderRoot.querySelector('.field') as Field;
}
protected getMenu() {
return this.element.renderRoot.querySelector('md-menu')!;
}
/**
* Shows the menu and returns the first list item element.
*/
Expand Down Expand Up @@ -48,6 +51,18 @@ export class SelectHarness extends Harness<Select> {
field.click();
}

async clickAndWaitForMenu() {
const menu = this.getMenu();
const menuOpen = menu.open === true;
const waitForMenu = new Promise<void>((resolve) => {
menu.addEventListener(menuOpen ? 'closed' : 'opened', () => {
resolve();
}, {once: true});
});
await this.click();
await waitForMenu;
}

async clickOption(index: number) {
const menu = this.element.renderRoot.querySelector('md-menu')!;
if (!menu.open) {
Expand Down
31 changes: 30 additions & 1 deletion select/select_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ describe('<md-outlined-select>', () => {
const selectEl = root.querySelector('md-outlined-select')!;
await selectEl.updateComplete;

await new SelectHarness(selectEl).clickOption(1);
const harness = new SelectHarness(selectEl);
await harness.clickAndWaitForMenu();
await harness.clickOption(1);

expect(changed).toBeTrue();
});
Expand Down Expand Up @@ -177,6 +179,33 @@ describe('<md-outlined-select>', () => {
],
});
});

it('closes select when field re-clicked', async () => {
render(
html`
<md-outlined-select>
<md-select-option selected></md-select-option>
<md-select-option></md-select-option>
</md-outlined-select>`,
root);
const selectEl = root.querySelector('md-outlined-select')!;
await selectEl.updateComplete;

const spanEl = selectEl.shadowRoot!.querySelector<HTMLElement>(
'span.select'
)!;
const menuEl = selectEl.shadowRoot!.querySelector('md-menu')!;

const harness = new SelectHarness(selectEl);
await harness.clickAndWaitForMenu();
expect(spanEl.classList.contains('open')).toBeTrue();
expect(menuEl.open).toBeTrue();

await harness.clickAndWaitForMenu();

expect(menuEl.open).toBeFalse();
expect(spanEl.classList.contains('open')).toBeFalse();
});
});

describe('<md-filled-select>', () => {
Expand Down

0 comments on commit 76537b0

Please sign in to comment.