Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dialog): support adding and removing classes via dialogRef #14772

Merged
merged 2 commits into from Jan 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 18 additions & 4 deletions src/cdk/overlay/overlay-ref.ts
Expand Up @@ -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;
}
Expand All @@ -298,17 +298,31 @@ 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[]): 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[]): void {
if (this._pane) {
this._toggleClasses(this._pane, classes, false);
}
}

/**
* Returns the layout direction of the overlay panel.
*/
Expand Down
20 changes: 20 additions & 0 deletions src/cdk/overlay/overlay.spec.ts
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion src/dev-app/dialog/dialog-demo.html
Expand Up @@ -123,5 +123,5 @@ <h2>Other options</h2>

<p> {{ data.message }} </p>
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>
<button (click)="dialogRef.updateSize('500px', '500px').updatePosition({ top: '25px', left: '25px' });">Change dimensions</button>`
<button (click)="dialogRef.updateSize('500px', '500px').updatePosition({top: '25px', left: '25px'});">Change dimensions</button>
</ng-template>
14 changes: 12 additions & 2 deletions src/dev-app/dialog/dialog-demo.ts
Expand Up @@ -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';


Expand Down Expand Up @@ -101,8 +101,11 @@ export class DialogDemo {
<p cdkDragHandle> {{ data.message }} </p>
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>
<button (click)="togglePosition()">Change dimensions</button>
<button (click)="temporarilyHide()">Hide for 2 seconds</button>
</div>
`
`,
encapsulation: ViewEncapsulation.None,
styles: [`.hidden-dialog { opacity: 0; }`]
})
export class JazzDialog {
private _dimesionToggle = false;
Expand All @@ -124,6 +127,13 @@ export class JazzDialog {
.updatePosition();
}
}

temporarilyHide(): void {
this.dialogRef.addPanelClass('hidden-dialog');
setTimeout(() => {
this.dialogRef.removePanelClass('hidden-dialog');
}, 2000);
}
}


Expand Down
12 changes: 12 additions & 0 deletions src/lib/dialog/dialog-ref.ts
Expand Up @@ -173,6 +173,18 @@ export class MatDialogRef<T, R = any> {
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.
Expand Down
17 changes: 17 additions & 0 deletions src/lib/dialog/dialog.spec.ts
Expand Up @@ -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, {
Expand Down
4 changes: 3 additions & 1 deletion tools/public_api_guard/cdk/overlay.d.ts
Expand Up @@ -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<OverlayConfig>, _ngZone: NgZone, _keyboardDispatcher: OverlayKeyboardDispatcher, _document: Document, _location?: Location | undefined);
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
addPanelClass(classes: string | string[]): void;
attach(portal: any): any;
attach<T>(portal: ComponentPortal<T>): ComponentRef<T>;
attach<T>(portal: TemplatePortal<T>): EmbeddedViewRef<T>;
attachments(): Observable<void>;
backdropClick(): Observable<MouseEvent>;
detach(): any;
Expand All @@ -240,6 +241,7 @@ export declare class OverlayRef implements PortalOutlet, OverlayReference {
getDirection(): Direction;
hasAttached(): boolean;
keydownEvents(): Observable<KeyboardEvent>;
removePanelClass(classes: string | string[]): void;
setDirection(dir: Direction | Directionality): void;
updatePosition(): void;
updatePositionStrategy(strategy: PositionStrategy): void;
Expand Down