Skip to content

Commit 2eb9f84

Browse files
committed
fix(material/autocomplete): reopen panel on input click
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 2eb9f84

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

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

Lines changed: 1 addition & 0 deletions
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)': 'openPanel()',
4445
},
4546
exportAs: 'matAutocompleteTrigger',
4647
providers: [MAT_AUTOCOMPLETE_VALUE_ACCESSOR],

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

Lines changed: 25 additions & 0 deletions
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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,10 @@ export abstract class _MatAutocompleteTriggerBase
245245

246246
/** Opens the autocomplete suggestion panel. */
247247
openPanel(): void {
248-
this._attachOverlay();
249-
this._floatLabel();
248+
if (!this.panelOpen) {
249+
this._attachOverlay();
250+
this._floatLabel();
251+
}
250252
}
251253

252254
/** Closes the autocomplete suggestion panel. */
@@ -800,6 +802,7 @@ export abstract class _MatAutocompleteTriggerBase
800802
'(blur)': '_onTouched()',
801803
'(input)': '_handleInput($event)',
802804
'(keydown)': '_handleKeydown($event)',
805+
'(click)': 'openPanel()',
803806
},
804807
exportAs: 'matAutocompleteTrigger',
805808
providers: [MAT_AUTOCOMPLETE_VALUE_ACCESSOR],

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 25 additions & 0 deletions
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(() => {

0 commit comments

Comments
 (0)