Skip to content

Commit b62f3f3

Browse files
willshowellvivian-hu-zz
authored andcommitted
feat(dialog): support adding and removing classes via dialogRef (#14772)
* feat(dialog): support adding/removing panelClasses to open dialogRef Fixes #6206 * address comments
1 parent 6f49813 commit b62f3f3

File tree

7 files changed

+83
-8
lines changed

7 files changed

+83
-8
lines changed

src/cdk/overlay/overlay-ref.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,14 +273,14 @@ export class OverlayRef implements PortalOutlet, OverlayReference {
273273
}
274274

275275
/** Updates the position of the overlay based on the position strategy. */
276-
updatePosition() {
276+
updatePosition(): void {
277277
if (this._positionStrategy) {
278278
this._positionStrategy.apply();
279279
}
280280
}
281281

282282
/** Switches to a new position strategy and updates the overlay position. */
283-
updatePositionStrategy(strategy: PositionStrategy) {
283+
updatePositionStrategy(strategy: PositionStrategy): void {
284284
if (strategy === this._positionStrategy) {
285285
return;
286286
}
@@ -298,17 +298,31 @@ export class OverlayRef implements PortalOutlet, OverlayReference {
298298
}
299299

300300
/** Update the size properties of the overlay. */
301-
updateSize(sizeConfig: OverlaySizeConfig) {
301+
updateSize(sizeConfig: OverlaySizeConfig): void {
302302
this._config = {...this._config, ...sizeConfig};
303303
this._updateElementSize();
304304
}
305305

306306
/** Sets the LTR/RTL direction for the overlay. */
307-
setDirection(dir: Direction | Directionality) {
307+
setDirection(dir: Direction | Directionality): void {
308308
this._config = {...this._config, direction: dir};
309309
this._updateElementDirection();
310310
}
311311

312+
/** Add a CSS class or an array of classes to the overlay pane. */
313+
addPanelClass(classes: string | string[]): void {
314+
if (this._pane) {
315+
this._toggleClasses(this._pane, classes, true);
316+
}
317+
}
318+
319+
/** Remove a CSS class or an array of classes from the overlay pane. */
320+
removePanelClass(classes: string | string[]): void {
321+
if (this._pane) {
322+
this._toggleClasses(this._pane, classes, false);
323+
}
324+
}
325+
312326
/**
313327
* Returns the layout direction of the overlay panel.
314328
*/

src/cdk/overlay/overlay.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,26 @@ describe('Overlay', () => {
398398
expect(overlayContainerElement.textContent).toBe('');
399399
});
400400

401+
it('should add and remove classes while open', () => {
402+
let overlayRef = overlay.create();
403+
overlayRef.attach(componentPortal);
404+
405+
const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
406+
expect(pane.classList)
407+
.not.toContain('custom-class-one', 'Expected class to be initially missing');
408+
409+
overlayRef.addPanelClass('custom-class-one');
410+
expect(pane.classList).toContain('custom-class-one', 'Expected class to be added');
411+
412+
overlayRef.removePanelClass('custom-class-one');
413+
expect(pane.classList).not.toContain('custom-class-one', 'Expected class to be removed');
414+
415+
// Destroy the overlay and make sure no errors are thrown when trying to alter
416+
// panel classes
417+
overlayRef.dispose();
418+
expect(() => overlayRef.addPanelClass('custom-class-two')).not.toThrowError();
419+
});
420+
401421
describe('positioning', () => {
402422
let config: OverlayConfig;
403423

src/dev-app/dialog/dialog-demo.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,5 +123,5 @@ <h2>Other options</h2>
123123

124124
<p> {{ data.message }} </p>
125125
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>
126-
<button (click)="dialogRef.updateSize('500px', '500px').updatePosition({ top: '25px', left: '25px' });">Change dimensions</button>`
126+
<button (click)="dialogRef.updateSize('500px', '500px').updatePosition({top: '25px', left: '25px'});">Change dimensions</button>
127127
</ng-template>

src/dev-app/dialog/dialog-demo.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {DOCUMENT} from '@angular/common';
10-
import {Component, Inject, TemplateRef, ViewChild} from '@angular/core';
10+
import {Component, Inject, TemplateRef, ViewChild, ViewEncapsulation} from '@angular/core';
1111
import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material';
1212

1313

@@ -101,8 +101,11 @@ export class DialogDemo {
101101
<p cdkDragHandle> {{ data.message }} </p>
102102
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>
103103
<button (click)="togglePosition()">Change dimensions</button>
104+
<button (click)="temporarilyHide()">Hide for 2 seconds</button>
104105
</div>
105-
`
106+
`,
107+
encapsulation: ViewEncapsulation.None,
108+
styles: [`.hidden-dialog { opacity: 0; }`]
106109
})
107110
export class JazzDialog {
108111
private _dimesionToggle = false;
@@ -124,6 +127,13 @@ export class JazzDialog {
124127
.updatePosition();
125128
}
126129
}
130+
131+
temporarilyHide(): void {
132+
this.dialogRef.addPanelClass('hidden-dialog');
133+
setTimeout(() => {
134+
this.dialogRef.removePanelClass('hidden-dialog');
135+
}, 2000);
136+
}
127137
}
128138

129139

src/lib/dialog/dialog-ref.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,18 @@ export class MatDialogRef<T, R = any> {
173173
return this;
174174
}
175175

176+
/** Add a CSS class or an array of classes to the overlay pane. */
177+
addPanelClass(classes: string | string[]): this {
178+
this._overlayRef.addPanelClass(classes);
179+
return this;
180+
}
181+
182+
/** Remove a CSS class or an array of classes from the overlay pane. */
183+
removePanelClass(classes: string | string[]): this {
184+
this._overlayRef.removePanelClass(classes);
185+
return this;
186+
}
187+
176188
/**
177189
* Gets an observable that is notified when the dialog is finished opening.
178190
* @deprecated Use `afterOpened` instead.

src/lib/dialog/dialog.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,23 @@ describe('MatDialog', () => {
830830
sibling.parentNode!.removeChild(sibling);
831831
}));
832832

833+
it('should add and remove classes while open', () => {
834+
let dialogRef = dialog.open(PizzaMsg, {
835+
disableClose: true,
836+
viewContainerRef: testViewContainerRef
837+
});
838+
839+
const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
840+
expect(pane.classList)
841+
.not.toContain('custom-class-one', 'Expected class to be initially missing');
842+
843+
dialogRef.addPanelClass('custom-class-one');
844+
expect(pane.classList).toContain('custom-class-one', 'Expected class to be added');
845+
846+
dialogRef.removePanelClass('custom-class-one');
847+
expect(pane.classList).not.toContain('custom-class-one', 'Expected class to be removed');
848+
});
849+
833850
describe('disableClose option', () => {
834851
it('should prevent closing via clicks on the backdrop', fakeAsync(() => {
835852
dialog.open(PizzaMsg, {

tools/public_api_guard/cdk/overlay.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,10 @@ export declare class OverlayRef implements PortalOutlet, OverlayReference {
227227
readonly hostElement: HTMLElement;
228228
readonly overlayElement: HTMLElement;
229229
constructor(_portalOutlet: PortalOutlet, _host: HTMLElement, _pane: HTMLElement, _config: ImmutableObject<OverlayConfig>, _ngZone: NgZone, _keyboardDispatcher: OverlayKeyboardDispatcher, _document: Document, _location?: Location | undefined);
230-
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
230+
addPanelClass(classes: string | string[]): void;
231231
attach(portal: any): any;
232232
attach<T>(portal: ComponentPortal<T>): ComponentRef<T>;
233+
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
233234
attachments(): Observable<void>;
234235
backdropClick(): Observable<MouseEvent>;
235236
detach(): any;
@@ -240,6 +241,7 @@ export declare class OverlayRef implements PortalOutlet, OverlayReference {
240241
getDirection(): Direction;
241242
hasAttached(): boolean;
242243
keydownEvents(): Observable<KeyboardEvent>;
244+
removePanelClass(classes: string | string[]): void;
243245
setDirection(dir: Direction | Directionality): void;
244246
updatePosition(): void;
245247
updatePositionStrategy(strategy: PositionStrategy): void;

0 commit comments

Comments
 (0)