Skip to content

Commit

Permalink
feat(dialog): add disableClose option (#1678)
Browse files Browse the repository at this point in the history
Adds a config option that allows users to disable closing a dialog via a backdrop click or pressing escape.

Fixes #1419.
  • Loading branch information
crisbeto authored and jelbourn committed Nov 3, 2016
1 parent 0d552f5 commit 93f8e04
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 13 deletions.
6 changes: 4 additions & 2 deletions src/lib/dialog/dialog-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ export class MdDialogConfig {
/** The ARIA role of the dialog element. */
role?: DialogRole = 'dialog';

// TODO(jelbourn): add configuration for size, clickOutsideToClose, lifecycle hooks,
// ARIA labelling.
/** Whether the user can use escape or clicking outside to close a modal. */
disableClose = false;

// TODO(jelbourn): add configuration for size, lifecycle hooks, ARIA labelling.
}
17 changes: 9 additions & 8 deletions src/lib/dialog/dialog-container.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
Component,
ComponentRef,
ViewChild,
ViewEncapsulation,
NgZone,
OnDestroy
Component,
ComponentRef,
ViewChild,
ViewEncapsulation,
NgZone,
OnDestroy,
} from '@angular/core';
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
import {MdDialogConfig} from './dialog-config';
Expand Down Expand Up @@ -74,8 +74,9 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {

/** Handles the user pressing the Escape key. */
handleEscapeKey() {
// TODO(jelbourn): add MdDialogConfig option to disable this behavior.
this.dialogRef.close();
if (!this.dialogConfig.disableClose) {
this.dialogRef.close();
}
}

ngOnDestroy() {
Expand Down
37 changes: 36 additions & 1 deletion src/lib/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,47 @@ describe('MdDialog', () => {

viewContainerFixture.detectChanges();

let backdrop = <HTMLElement> overlayContainerElement.querySelector('.md-overlay-backdrop');
let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
backdrop.click();

expect(overlayContainerElement.querySelector('md-dialog-container')).toBeFalsy();
});

describe('disableClose option', () => {
it('should prevent closing via clicks on the backdrop', () => {
let config = new MdDialogConfig();
config.viewContainerRef = testViewContainerRef;
config.disableClose = true;

dialog.open(PizzaMsg, config);

viewContainerFixture.detectChanges();

let backdrop = overlayContainerElement.querySelector('.md-overlay-backdrop') as HTMLElement;
backdrop.click();

expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy();
});

it('should prevent closing via the escape key', () => {
let config = new MdDialogConfig();
config.viewContainerRef = testViewContainerRef;
config.disableClose = true;

dialog.open(PizzaMsg, config);

viewContainerFixture.detectChanges();

let dialogContainer: MdDialogContainer = viewContainerFixture.debugElement.query(
By.directive(MdDialogContainer)).componentInstance;

// Fake the user pressing the escape key by calling the handler directly.
dialogContainer.handleEscapeKey();

expect(overlayContainerElement.querySelector('md-dialog-container')).toBeTruthy();
});
});

describe('focus management', () => {

// When testing focus, all of the elements must be in the DOM.
Expand Down
6 changes: 4 additions & 2 deletions src/lib/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,10 @@ export class MdDialog {
// to modify and close it.
let dialogRef = <MdDialogRef<T>> new MdDialogRef(overlayRef);

// When the dialog backdrop is clicked, we want to close it.
overlayRef.backdropClick().first().subscribe(() => dialogRef.close());
if (!dialogContainer.dialogConfig.disableClose) {
// When the dialog backdrop is clicked, we want to close it.
overlayRef.backdropClick().first().subscribe(() => dialogRef.close());
}

// Set the dialogRef to the container so that it can use the ref to close the dialog.
dialogContainer.dialogRef = dialogRef;
Expand Down

0 comments on commit 93f8e04

Please sign in to comment.