diff --git a/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts b/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts
index 621e2d69855e..7e89caf5b08b 100644
--- a/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts
+++ b/src/material-experimental/mdc-autocomplete/autocomplete.spec.ts
@@ -208,6 +208,20 @@ describe('MDC-based MatAutocomplete', () => {
.toEqual('');
}));
+ it('should close the panel when clicking away and propagation is stopped', fakeAsync(() => {
+ const trigger = fixture.componentInstance.trigger;
+ dispatchFakeEvent(input, 'focusin');
+ fixture.detectChanges();
+ zone.simulateZoneExit();
+
+ expect(trigger.panelOpen).toBe(true, 'Expected panel to be open.');
+
+ fixture.nativeElement.querySelector('.stop-propagation').click();
+ fixture.detectChanges();
+
+ expect(trigger.panelOpen).toBe(false, 'Expected panel to be closed.');
+ }));
+
it('should close the panel when the user taps away on a touch device', fakeAsync(() => {
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();
@@ -3374,6 +3388,8 @@ const SIMPLE_AUTOCOMPLETE_TEMPLATE = `
{{ state.code }}: {{ state.name }}
+
+
`;
@Component({template: SIMPLE_AUTOCOMPLETE_TEMPLATE})
diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts
index 50a205af693f..c55692934058 100644
--- a/src/material/autocomplete/autocomplete-trigger.ts
+++ b/src/material/autocomplete/autocomplete-trigger.ts
@@ -349,10 +349,12 @@ export abstract class _MatAutocompleteTriggerBase
/** Stream of clicks outside of the autocomplete panel. */
private _getOutsideClickStream(): Observable {
+ // Use capturing so we can close even if propagation is stopped.
+ const eventOptions = {capture: true};
return merge(
- fromEvent(this._document, 'click') as Observable,
- fromEvent(this._document, 'auxclick') as Observable,
- fromEvent(this._document, 'touchend') as Observable,
+ fromEvent(this._document, 'click', eventOptions) as Observable,
+ fromEvent(this._document, 'auxclick', eventOptions) as Observable,
+ fromEvent(this._document, 'touchend', eventOptions) as Observable,
).pipe(
filter(event => {
// If we're in the Shadow DOM, the event target will be the shadow root, so we have to
diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts
index ed41c3acbceb..5b08d705e4d6 100644
--- a/src/material/autocomplete/autocomplete.spec.ts
+++ b/src/material/autocomplete/autocomplete.spec.ts
@@ -210,6 +210,20 @@ describe('MatAutocomplete', () => {
.toEqual('');
}));
+ it('should close the panel when clicking away and propagation is stopped', fakeAsync(() => {
+ const trigger = fixture.componentInstance.trigger;
+ dispatchFakeEvent(input, 'focusin');
+ fixture.detectChanges();
+ zone.simulateZoneExit();
+
+ expect(trigger.panelOpen).toBe(true, 'Expected panel to be open.');
+
+ fixture.nativeElement.querySelector('.stop-propagation').click();
+ fixture.detectChanges();
+
+ expect(trigger.panelOpen).toBe(false, 'Expected panel to be closed.');
+ }));
+
it('should close the panel when the user taps away on a touch device', fakeAsync(() => {
dispatchFakeEvent(input, 'focus');
fixture.detectChanges();
@@ -3379,6 +3393,8 @@ const SIMPLE_AUTOCOMPLETE_TEMPLATE = `
{{ state.code }}: {{ state.name }}
+
+
`;
@Component({template: SIMPLE_AUTOCOMPLETE_TEMPLATE})