From 728480da8b522309d1575ae8a43a92a9ecc032e8 Mon Sep 17 00:00:00 2001 From: Will Howell Date: Wed, 9 Jan 2019 13:31:28 -0500 Subject: [PATCH 1/2] feat(dialog): support adding/removing panelClasses to open dialogRef Fixes #6206 --- src/cdk/overlay/overlay-ref.ts | 14 ++++++++++++++ src/cdk/overlay/overlay.spec.ts | 20 ++++++++++++++++++++ src/dev-app/dialog/dialog-demo.html | 2 +- src/dev-app/dialog/dialog-demo.ts | 14 ++++++++++++-- src/lib/dialog/dialog-ref.ts | 12 ++++++++++++ src/lib/dialog/dialog.spec.ts | 17 +++++++++++++++++ 6 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index 5c6ddb1b5708..b00a5509b872 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -309,6 +309,20 @@ export class OverlayRef implements PortalOutlet, OverlayReference { this._updateElementDirection(); } + /** Add a CSS class or an array of classes to the overlay pane. */ + addPanelClass(classes: string | string[]) { + if (this._pane) { + this._toggleClasses(this._pane, classes, true); + } + } + + /** Remove a CSS class or an array of classes from the overlay pane. */ + removePanelClass(classes: string | string[]) { + if (this._pane) { + this._toggleClasses(this._pane, classes, false); + } + } + /** * Returns the layout direction of the overlay panel. */ diff --git a/src/cdk/overlay/overlay.spec.ts b/src/cdk/overlay/overlay.spec.ts index fc0555ddf7bd..f7da3fc088e7 100644 --- a/src/cdk/overlay/overlay.spec.ts +++ b/src/cdk/overlay/overlay.spec.ts @@ -398,6 +398,26 @@ describe('Overlay', () => { expect(overlayContainerElement.textContent).toBe(''); }); + it('should add and remove classes while open', () => { + let overlayRef = overlay.create(); + overlayRef.attach(componentPortal); + + const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + expect(pane.classList) + .not.toContain('custom-class-one', 'Expected class to be initially missing'); + + overlayRef.addPanelClass('custom-class-one'); + expect(pane.classList).toContain('custom-class-one', 'Expected class to be added'); + + overlayRef.removePanelClass('custom-class-one'); + expect(pane.classList).not.toContain('custom-class-one', 'Expected class to be removed'); + + // Destroy the overlay and make sure no errors are thrown when trying to alter + // panel classes + overlayRef.dispose(); + expect(() => overlayRef.addPanelClass('custom-class-two')).not.toThrowError(); + }); + describe('positioning', () => { let config: OverlayConfig; diff --git a/src/dev-app/dialog/dialog-demo.html b/src/dev-app/dialog/dialog-demo.html index ebf76c003267..516d2fbb63e3 100644 --- a/src/dev-app/dialog/dialog-demo.html +++ b/src/dev-app/dialog/dialog-demo.html @@ -123,5 +123,5 @@

Other options

{{ data.message }}

- ` + diff --git a/src/dev-app/dialog/dialog-demo.ts b/src/dev-app/dialog/dialog-demo.ts index b3640fa356be..d79a59931bdd 100644 --- a/src/dev-app/dialog/dialog-demo.ts +++ b/src/dev-app/dialog/dialog-demo.ts @@ -7,7 +7,7 @@ */ import {DOCUMENT} from '@angular/common'; -import {Component, Inject, TemplateRef, ViewChild} from '@angular/core'; +import {Component, Inject, TemplateRef, ViewChild, ViewEncapsulation} from '@angular/core'; import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material'; @@ -101,8 +101,11 @@ export class DialogDemo {

{{ data.message }}

+ - ` + `, + encapsulation: ViewEncapsulation.None, + styles: [`.hidden-dialog { opacity: 0; }`] }) export class JazzDialog { private _dimesionToggle = false; @@ -124,6 +127,13 @@ export class JazzDialog { .updatePosition(); } } + + temporarilyHide(): void { + this.dialogRef.addPanelClass('hidden-dialog'); + setTimeout(() => { + this.dialogRef.removePanelClass('hidden-dialog'); + }, 2000); + } } diff --git a/src/lib/dialog/dialog-ref.ts b/src/lib/dialog/dialog-ref.ts index 98af86092b9e..490e5699480d 100644 --- a/src/lib/dialog/dialog-ref.ts +++ b/src/lib/dialog/dialog-ref.ts @@ -173,6 +173,18 @@ export class MatDialogRef { return this; } + /** Add a CSS class or an array of classes to the overlay pane. */ + addPanelClass(classes: string | string[]): this { + this._overlayRef.addPanelClass(classes); + return this; + } + + /** Remove a CSS class or an array of classes from the overlay pane. */ + removePanelClass(classes: string | string[]): this { + this._overlayRef.removePanelClass(classes); + return this; + } + /** * Gets an observable that is notified when the dialog is finished opening. * @deprecated Use `afterOpened` instead. diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index d66934fa3b00..1195958d9fff 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -830,6 +830,23 @@ describe('MatDialog', () => { sibling.parentNode!.removeChild(sibling); })); + it('should add and remove classes while open', () => { + let dialogRef = dialog.open(PizzaMsg, { + disableClose: true, + viewContainerRef: testViewContainerRef + }); + + const pane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + expect(pane.classList) + .not.toContain('custom-class-one', 'Expected class to be initially missing'); + + dialogRef.addPanelClass('custom-class-one'); + expect(pane.classList).toContain('custom-class-one', 'Expected class to be added'); + + dialogRef.removePanelClass('custom-class-one'); + expect(pane.classList).not.toContain('custom-class-one', 'Expected class to be removed'); + }); + describe('disableClose option', () => { it('should prevent closing via clicks on the backdrop', fakeAsync(() => { dialog.open(PizzaMsg, { From 6fb7422a6c25c506bfe9014bfbfa11191435d491 Mon Sep 17 00:00:00 2001 From: Will Howell Date: Wed, 9 Jan 2019 17:29:27 -0500 Subject: [PATCH 2/2] address comments --- src/cdk/overlay/overlay-ref.ts | 12 ++++++------ src/dev-app/dialog/dialog-demo.html | 2 +- tools/public_api_guard/cdk/overlay.d.ts | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/cdk/overlay/overlay-ref.ts b/src/cdk/overlay/overlay-ref.ts index b00a5509b872..bfb0fbff1db1 100644 --- a/src/cdk/overlay/overlay-ref.ts +++ b/src/cdk/overlay/overlay-ref.ts @@ -273,14 +273,14 @@ export class OverlayRef implements PortalOutlet, OverlayReference { } /** Updates the position of the overlay based on the position strategy. */ - updatePosition() { + updatePosition(): void { if (this._positionStrategy) { this._positionStrategy.apply(); } } /** Switches to a new position strategy and updates the overlay position. */ - updatePositionStrategy(strategy: PositionStrategy) { + updatePositionStrategy(strategy: PositionStrategy): void { if (strategy === this._positionStrategy) { return; } @@ -298,26 +298,26 @@ export class OverlayRef implements PortalOutlet, OverlayReference { } /** Update the size properties of the overlay. */ - updateSize(sizeConfig: OverlaySizeConfig) { + updateSize(sizeConfig: OverlaySizeConfig): void { this._config = {...this._config, ...sizeConfig}; this._updateElementSize(); } /** Sets the LTR/RTL direction for the overlay. */ - setDirection(dir: Direction | Directionality) { + setDirection(dir: Direction | Directionality): void { this._config = {...this._config, direction: dir}; this._updateElementDirection(); } /** Add a CSS class or an array of classes to the overlay pane. */ - addPanelClass(classes: string | string[]) { + addPanelClass(classes: string | string[]): void { if (this._pane) { this._toggleClasses(this._pane, classes, true); } } /** Remove a CSS class or an array of classes from the overlay pane. */ - removePanelClass(classes: string | string[]) { + removePanelClass(classes: string | string[]): void { if (this._pane) { this._toggleClasses(this._pane, classes, false); } diff --git a/src/dev-app/dialog/dialog-demo.html b/src/dev-app/dialog/dialog-demo.html index 516d2fbb63e3..7605af0d8911 100644 --- a/src/dev-app/dialog/dialog-demo.html +++ b/src/dev-app/dialog/dialog-demo.html @@ -123,5 +123,5 @@

Other options

{{ data.message }}

- + diff --git a/tools/public_api_guard/cdk/overlay.d.ts b/tools/public_api_guard/cdk/overlay.d.ts index fc48e7f2f955..81c60a7a26aa 100644 --- a/tools/public_api_guard/cdk/overlay.d.ts +++ b/tools/public_api_guard/cdk/overlay.d.ts @@ -227,9 +227,10 @@ export declare class OverlayRef implements PortalOutlet, OverlayReference { readonly hostElement: HTMLElement; readonly overlayElement: HTMLElement; constructor(_portalOutlet: PortalOutlet, _host: HTMLElement, _pane: HTMLElement, _config: ImmutableObject, _ngZone: NgZone, _keyboardDispatcher: OverlayKeyboardDispatcher, _document: Document, _location?: Location | undefined); - attach(portal: TemplatePortal): EmbeddedViewRef; + addPanelClass(classes: string | string[]): void; attach(portal: any): any; attach(portal: ComponentPortal): ComponentRef; + attach(portal: TemplatePortal): EmbeddedViewRef; attachments(): Observable; backdropClick(): Observable; detach(): any; @@ -240,6 +241,7 @@ export declare class OverlayRef implements PortalOutlet, OverlayReference { getDirection(): Direction; hasAttached(): boolean; keydownEvents(): Observable; + removePanelClass(classes: string | string[]): void; setDirection(dir: Direction | Directionality): void; updatePosition(): void; updatePositionStrategy(strategy: PositionStrategy): void;