Skip to content

Commit 540226c

Browse files
crisbetommalerba
authored andcommitted
feat(overlay): allow multiple classes to be assigned to the backdrop (#10531)
Adds the ability to pass in an array of CSS classes to the `backdropClass`. Fixes #10529.
1 parent 99f39ca commit 540226c

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

src/cdk/overlay/overlay-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class OverlayConfig {
2727
hasBackdrop?: boolean = false;
2828

2929
/** Custom class to add to the backdrop */
30-
backdropClass?: string = 'cdk-overlay-dark-backdrop';
30+
backdropClass?: string | string[] = 'cdk-overlay-dark-backdrop';
3131

3232
/** The width of the overlay panel. If a number is provided, pixel units are assumed. */
3333
width?: number | string;

src/cdk/overlay/overlay-ref.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {Observable, Subject} from 'rxjs';
1313
import {take} from 'rxjs/operators';
1414
import {OverlayKeyboardDispatcher} from './keyboard/overlay-keyboard-dispatcher';
1515
import {OverlayConfig} from './overlay-config';
16-
import {coerceCssPixelValue} from '@angular/cdk/coercion';
16+
import {coerceCssPixelValue, coerceArray} from '@angular/cdk/coercion';
1717

1818

1919
/** An object where all of its properties cannot be written. */
@@ -115,12 +115,7 @@ export class OverlayRef implements PortalOutlet {
115115
}
116116

117117
if (this._config.panelClass) {
118-
// We can't do a spread here, because IE doesn't support setting multiple classes.
119-
if (Array.isArray(this._config.panelClass)) {
120-
this._config.panelClass.forEach(cssClass => this._pane.classList.add(cssClass));
121-
} else {
122-
this._pane.classList.add(this._config.panelClass);
123-
}
118+
this._toggleClasses(this._pane, this._config.panelClass, true);
124119
}
125120

126121
// Only emit the `attachments` event once all other setup is done.
@@ -292,7 +287,7 @@ export class OverlayRef implements PortalOutlet {
292287
this._backdropElement.classList.add('cdk-overlay-backdrop');
293288

294289
if (this._config.backdropClass) {
295-
this._backdropElement.classList.add(this._config.backdropClass);
290+
this._toggleClasses(this._backdropElement, this._config.backdropClass, true);
296291
}
297292

298293
// Insert the backdrop before the pane in the DOM order,
@@ -353,7 +348,7 @@ export class OverlayRef implements PortalOutlet {
353348
backdropToDetach.classList.remove('cdk-overlay-backdrop-showing');
354349

355350
if (this._config.backdropClass) {
356-
backdropToDetach.classList.remove(this._config.backdropClass);
351+
this._toggleClasses(backdropToDetach, this._config.backdropClass, false);
357352
}
358353

359354
backdropToDetach.addEventListener('transitionend', finishDetach);
@@ -368,6 +363,16 @@ export class OverlayRef implements PortalOutlet {
368363
this._ngZone.runOutsideAngular(() => setTimeout(finishDetach, 500));
369364
}
370365
}
366+
367+
/** Toggles a single CSS class or an array of classes on an element. */
368+
private _toggleClasses(element: HTMLElement, cssClasses: string | string[], isAdd: boolean) {
369+
const classList = element.classList;
370+
371+
coerceArray(cssClasses).forEach(cssClass => {
372+
// We can't do a spread here, because IE doesn't support setting multiple classes.
373+
isAdd ? classList.add(cssClass) : classList.remove(cssClass);
374+
});
375+
}
371376
}
372377

373378

src/cdk/overlay/overlay.spec.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ describe('Overlay', () => {
442442
expect(backdrop.classList).toContain('cdk-overlay-dark-backdrop');
443443
});
444444

445-
it('should apply a custom overlay backdrop class', () => {
445+
it('should apply a custom class to the backdrop', () => {
446446
config.backdropClass = 'cdk-overlay-transparent-backdrop';
447447

448448
let overlayRef = overlay.create(config);
@@ -453,6 +453,18 @@ describe('Overlay', () => {
453453
expect(backdrop.classList).toContain('cdk-overlay-transparent-backdrop');
454454
});
455455

456+
it('should apply multiple custom classes to the overlay', () => {
457+
config.backdropClass = ['custom-class-1', 'custom-class-2'];
458+
459+
let overlayRef = overlay.create(config);
460+
overlayRef.attach(componentPortal);
461+
viewContainerFixture.detectChanges();
462+
463+
let backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
464+
expect(backdrop.classList).toContain('custom-class-1');
465+
expect(backdrop.classList).toContain('custom-class-2');
466+
});
467+
456468
it('should disable the pointer events of a backdrop that is being removed', () => {
457469
let overlayRef = overlay.create(config);
458470
overlayRef.attach(componentPortal);

0 commit comments

Comments
 (0)