Skip to content

Commit 16dea18

Browse files
authored
fix(material/autocomplete): reopen panel on input click (#16020)
Currently if the user clicks an autocomplete to open it, selects an option and then clicks again, the panel won't open, because we use `focus` and the input was focused already. These changes add an extra `click` listener so the panel can reopen. Fixes #15177.
1 parent 8a12da7 commit 16dea18

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed

src/material-experimental/mdc-autocomplete/autocomplete-trigger.ts

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export const MAT_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
4141
'(blur)': '_onTouched()',
4242
'(input)': '_handleInput($event)',
4343
'(keydown)': '_handleKeydown($event)',
44+
'(click)': '_handleClick()',
4445
},
4546
exportAs: 'matAutocompleteTrigger',
4647
providers: [MAT_AUTOCOMPLETE_VALUE_ACCESSOR],

src/material-experimental/mdc-autocomplete/autocomplete.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,31 @@ describe('MDC-based MatAutocomplete', () => {
569569

570570
expect(input.hasAttribute('aria-haspopup')).toBe(false);
571571
});
572+
573+
it('should close the panel when pressing escape', fakeAsync(() => {
574+
const trigger = fixture.componentInstance.trigger;
575+
576+
input.focus();
577+
flush();
578+
fixture.detectChanges();
579+
580+
expect(document.activeElement).withContext('Expected input to be focused.').toBe(input);
581+
expect(trigger.panelOpen).withContext('Expected panel to be open.').toBe(true);
582+
583+
trigger.closePanel();
584+
fixture.detectChanges();
585+
586+
expect(document.activeElement)
587+
.withContext('Expected input to continue to be focused.')
588+
.toBe(input);
589+
expect(trigger.panelOpen).withContext('Expected panel to be closed.').toBe(false);
590+
591+
input.click();
592+
flush();
593+
fixture.detectChanges();
594+
595+
expect(trigger.panelOpen).withContext('Expected panel to reopen on click.').toBe(true);
596+
}));
572597
});
573598

574599
it('should not close the panel when clicking on the input', fakeAsync(() => {

src/material/autocomplete/autocomplete-trigger.ts

+7
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,12 @@ export abstract class _MatAutocompleteTriggerBase
454454
}
455455
}
456456

457+
_handleClick(): void {
458+
if (this._canOpen() && !this.panelOpen) {
459+
this.openPanel();
460+
}
461+
}
462+
457463
/**
458464
* In "auto" mode, the label will animate down as soon as focus is lost.
459465
* This causes the value to jump when selecting an option with the mouse.
@@ -800,6 +806,7 @@ export abstract class _MatAutocompleteTriggerBase
800806
'(blur)': '_onTouched()',
801807
'(input)': '_handleInput($event)',
802808
'(keydown)': '_handleKeydown($event)',
809+
'(click)': '_handleClick()',
803810
},
804811
exportAs: 'matAutocompleteTrigger',
805812
providers: [MAT_AUTOCOMPLETE_VALUE_ACCESSOR],

src/material/autocomplete/autocomplete.spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,31 @@ describe('MatAutocomplete', () => {
566566

567567
expect(input.hasAttribute('aria-haspopup')).toBe(false);
568568
});
569+
570+
it('should close the panel when pressing escape', fakeAsync(() => {
571+
const trigger = fixture.componentInstance.trigger;
572+
573+
input.focus();
574+
flush();
575+
fixture.detectChanges();
576+
577+
expect(document.activeElement).withContext('Expected input to be focused.').toBe(input);
578+
expect(trigger.panelOpen).withContext('Expected panel to be open.').toBe(true);
579+
580+
trigger.closePanel();
581+
fixture.detectChanges();
582+
583+
expect(document.activeElement)
584+
.withContext('Expected input to continue to be focused.')
585+
.toBe(input);
586+
expect(trigger.panelOpen).withContext('Expected panel to be closed.').toBe(false);
587+
588+
input.click();
589+
flush();
590+
fixture.detectChanges();
591+
592+
expect(trigger.panelOpen).withContext('Expected panel to reopen on click.').toBe(true);
593+
}));
569594
});
570595

571596
it('should not close the panel when clicking on the input', fakeAsync(() => {

tools/public_api_guard/material/autocomplete.md

+2
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ export abstract class _MatAutocompleteTriggerBase implements ControlValueAccesso
198198
closePanel(): void;
199199
connectedTo: _MatAutocompleteOriginBase;
200200
// (undocumented)
201+
_handleClick(): void;
202+
// (undocumented)
201203
_handleFocus(): void;
202204
// (undocumented)
203205
_handleInput(event: KeyboardEvent): void;

0 commit comments

Comments
 (0)