mirror of
https://github.com/material-components/material-web.git
synced 2026-01-09 07:21:09 +08:00
fix(select): close select on menu close
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`.
This commit is contained in:
parent
ec0a8ebf6e
commit
58bea9ce07
@ -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.
|
||||
*/
|
||||
@ -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) {
|
||||
|
||||
@ -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();
|
||||
});
|
||||
@ -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>', () => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user