From ad3be3cd65fa91736658250260bbdf400b9c65cb Mon Sep 17 00:00:00 2001
From: DavidACCarvalho <85346154+DavidACCarvalho@users.noreply.github.com>
Date: Tue, 18 Mar 2025 10:54:39 +0000
Subject: [PATCH 1/2] fix(material/select): close panel on detach output event
(#30634)
---
src/material/select/select.html | 1 +
src/material/select/select.spec.ts | 48 ++++++++++++++++++++++++++----
2 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/src/material/select/select.html b/src/material/select/select.html
index 9a9b147c3c51..6eaecee7f5c3 100644
--- a/src/material/select/select.html
+++ b/src/material/select/select.html
@@ -40,6 +40,7 @@
[cdkConnectedOverlayPositions]="_positions"
[cdkConnectedOverlayWidth]="_overlayWidth"
[cdkConnectedOverlayFlexibleDimensions]="true"
+ (detach)="close()"
(backdropClick)="close()"
(overlayKeydown)="_handleOverlayKeydown($event)">
{
.withContext('Expected select element to remain focused.')
.toBe(true);
}));
+
+ it('should close the panel on scroll event when MAT_SELECT_SCROLL_STRATEGY token was defined with CloseScrollStrategy', fakeAsync(() => {
+ // Need to recreate the testing module, because the issue we're
+ // testing for only the MAT_SELECT_SCROLL_STRATEGY is defined with thw
+ // is defined with the CloseScrollStrategy
+
+ TestBed.resetTestingModule();
+ TestBed.configureTestingModule({
+ imports: [MatFormFieldModule, MatSelectModule],
+ declarations: [BasicSelect],
+ providers: [
+ {
+ provide: MAT_SELECT_SCROLL_STRATEGY,
+ useFactory: (overlay: Overlay) => (): CloseScrollStrategy =>
+ overlay.scrollStrategies.close(),
+ deps: [Overlay],
+ },
+ {
+ provide: ScrollDispatcher,
+ useFactory: () => ({
+ scrolled: () => scrolledSubject,
+ }),
+ },
+ ],
+ });
+
+ fixture = TestBed.createComponent(BasicSelect);
+ fixture.detectChanges();
+
+ const select = fixture.componentInstance.select;
+ select.open();
+
+ scrolledSubject.next();
+ fixture.detectChanges();
+ flush();
+
+ expect(select.panelOpen).toBe(false);
+ }));
});
describe('selection logic', () => {
From e23bbdfe08c196c51dae0e75094f1abdf9d3cac6 Mon Sep 17 00:00:00 2001
From: Karan Mistry
Date: Tue, 18 Mar 2025 20:52:06 +0530
Subject: [PATCH 2/2] fix(material/autocomplete): allow overlay backdrop by
setting hasBackdrop option (#30631)
Currently when we open the panel, backdrop is not allowed and is not inline with `mat-select`, `mat-menu`, etc. This fix will align autocomplete with those components and give an option to configure it.
Fixes #30457
---
goldens/material/autocomplete/index.api.md | 2 +
.../autocomplete/autocomplete-trigger.ts | 2 +
.../autocomplete/autocomplete.spec.ts | 48 +++++++++++++++++++
src/material/autocomplete/autocomplete.ts | 7 +++
4 files changed, 59 insertions(+)
diff --git a/goldens/material/autocomplete/index.api.md b/goldens/material/autocomplete/index.api.md
index edc45ad80fae..912850144c22 100644
--- a/goldens/material/autocomplete/index.api.md
+++ b/goldens/material/autocomplete/index.api.md
@@ -131,6 +131,8 @@ export interface MatAutocompleteActivatedEvent {
export interface MatAutocompleteDefaultOptions {
autoActiveFirstOption?: boolean;
autoSelectActiveOption?: boolean;
+ backdropClass?: string;
+ hasBackdrop?: boolean;
hideSingleSelectionIndicator?: boolean;
overlayPanelClass?: string | string[];
requireSelection?: boolean;
diff --git a/src/material/autocomplete/autocomplete-trigger.ts b/src/material/autocomplete/autocomplete-trigger.ts
index 5127fd85fecd..22f2f93f3cd3 100644
--- a/src/material/autocomplete/autocomplete-trigger.ts
+++ b/src/material/autocomplete/autocomplete-trigger.ts
@@ -899,6 +899,8 @@ export class MatAutocompleteTrigger
scrollStrategy: this._scrollStrategy(),
width: this._getPanelWidth(),
direction: this._dir ?? undefined,
+ hasBackdrop: this._defaults?.hasBackdrop,
+ backdropClass: this._defaults?.backdropClass,
panelClass: this._defaults?.overlayPanelClass,
});
}
diff --git a/src/material/autocomplete/autocomplete.spec.ts b/src/material/autocomplete/autocomplete.spec.ts
index 2b7bb5ba3f8b..9a27005487f9 100644
--- a/src/material/autocomplete/autocomplete.spec.ts
+++ b/src/material/autocomplete/autocomplete.spec.ts
@@ -3014,6 +3014,54 @@ describe('MatAutocomplete', () => {
});
});
+ describe('with backdrop in options', () => {
+ it('should not contain backdrop by default', fakeAsync(() => {
+ const fixture = createComponent(SimpleAutocomplete, []);
+ fixture.detectChanges();
+ fixture.componentInstance.trigger.openPanel();
+ fixture.detectChanges();
+
+ tick(500);
+
+ expect(overlayContainerElement.querySelector('.cdk-overlay-backdrop')).toBeFalsy();
+ }));
+
+ it('should be able to add the backdrop using hasBackdrop option', fakeAsync(() => {
+ const fixture = createComponent(SimpleAutocomplete, [
+ {
+ provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
+ useValue: {hasBackdrop: true},
+ },
+ ]);
+ fixture.detectChanges();
+ fixture.componentInstance.trigger.openPanel();
+ fixture.detectChanges();
+
+ tick(500);
+
+ expect(overlayContainerElement.querySelector('.cdk-overlay-backdrop')).toBeTruthy();
+ }));
+ });
+
+ describe('with hasBackdrop and backdropClass in options', () => {
+ it('should be able to configure custom backdrop class', fakeAsync(() => {
+ const fixture = createComponent(SimpleAutocomplete, [
+ {
+ provide: MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
+ useValue: {backdropClass: 'my-custom-backdrop-class', hasBackdrop: true},
+ },
+ ]);
+ fixture.detectChanges();
+ fixture.componentInstance.trigger.openPanel();
+ fixture.detectChanges();
+
+ tick(500);
+
+ const cdkPanelElement = overlayContainerElement.querySelector('.cdk-overlay-backdrop');
+ expect(cdkPanelElement?.classList).toContain('my-custom-backdrop-class');
+ }));
+ });
+
describe('misc', () => {
it('should allow basic use without any forms directives', () => {
expect(() => {
diff --git a/src/material/autocomplete/autocomplete.ts b/src/material/autocomplete/autocomplete.ts
index 5a59d5581a31..89993cdf0003 100644
--- a/src/material/autocomplete/autocomplete.ts
+++ b/src/material/autocomplete/autocomplete.ts
@@ -70,6 +70,12 @@ export interface MatAutocompleteDefaultOptions {
*/
requireSelection?: boolean;
+ /** Class to be applied to the autocomplete's backdrop. */
+ backdropClass?: string;
+
+ /** Whether the autocomplete has a backdrop. */
+ hasBackdrop?: boolean;
+
/** Class or list of classes to be applied to the autocomplete's overlay panel. */
overlayPanelClass?: string | string[];
@@ -97,6 +103,7 @@ export function MAT_AUTOCOMPLETE_DEFAULT_OPTIONS_FACTORY(): MatAutocompleteDefau
autoSelectActiveOption: false,
hideSingleSelectionIndicator: false,
requireSelection: false,
+ hasBackdrop: false,
};
}