Skip to content

feat(dialog): add styles and ability to close. #862

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

Merged
merged 1 commit into from
Jul 15, 2016
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/components/dialog/dialog-container.scss
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
@import 'elevation';
@import 'default-theme';

$md-dialog-padding: 24px !default;

:host {
// TODO(jelbourn): add real Material Design dialog styles.
display: block;
background: deeppink;
@include md-elevation(2);
overflow: hidden;

padding: $md-dialog-padding;

background: md-color($md-background, dialog);
@include md-elevation(24);
}
29 changes: 28 additions & 1 deletion src/components/dialog/dialog-ref.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@
import {OverlayRef} from '@angular2-material/core/overlay/overlay-ref';
import {Observable} from 'rxjs/Observable';
import {Subject} from 'rxjs/Subject';


// TODO(jelbourn): resizing
// TODO(jelbourn): afterOpen and beforeClose


/**
* Reference to a dialog opened via the MdDialog service.
*/
export class MdDialogRef<T> {
/** The instance of component opened into the dialog. */
componentInstance: T;

// TODO(jelbourn): Add methods to resize, close, and get results from the dialog.
/** Subject for notifying the user that the dialog has finished closing. */
private _afterClosed: Subject<any> = new Subject();

constructor(private _overlayRef: OverlayRef) { }

/**
* Close the dialog.
* @param dialogResult Optional result to return to the dialog opener.
*/
close(dialogResult?: any): void {
this._overlayRef.dispose();
this._afterClosed.next(dialogResult);
this._afterClosed.complete();
}

/** Gets an observable that is notified when the dialog is finished closing. */
afterClosed(): Observable<any> {
return this._afterClosed.asObservable();
}
}
23 changes: 23 additions & 0 deletions src/components/dialog/dialog.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,29 @@ describe('MdDialog', () => {

detectChangesForDialogOpen(viewContainerFixture);
}));

it('should close a dialog and get back a result', async(() => {
let config = new MdDialogConfig();
config.viewContainerRef = testViewContainerRef;

dialog.open(PizzaMsg, config).then(dialogRef => {
viewContainerFixture.detectChanges();

let afterCloseResult: string;
dialogRef.afterClosed().subscribe(result => {
afterCloseResult = result;
});

dialogRef.close('Charmander');

viewContainerFixture.whenStable().then(() => {
expect(afterCloseResult).toBe('Charmander');
expect(overlayContainerElement.childNodes.length).toBe(0);
});
});

detectChangesForDialogOpen(viewContainerFixture);
}));
});


Expand Down
19 changes: 12 additions & 7 deletions src/components/dialog/dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@ export class MdDialog {
* @param config
*/
open<T>(component: ComponentType<T>, config: MdDialogConfig): Promise<MdDialogRef<T>> {
let overlayRef: OverlayRef;

return this._createOverlay(config)
.then(overlayRef => this._attachDialogContainer(overlayRef, config))
.then(containerRef => this._attachDialogContent(component, containerRef));
.then(overlay => overlayRef = overlay)
.then(overlay => this._attachDialogContainer(overlay, config))
.then(containerRef => this._attachDialogContent(component, containerRef, overlayRef));
}

/**
Expand All @@ -54,14 +57,14 @@ export class MdDialog {

/**
* Attaches an MdDialogContainer to a dialog's already-created overlay.
* @param overlayRef Reference to the dialog's underlying overlay.
* @param overlay Reference to the dialog's underlying overlay.
* @param config The dialog configuration.
* @returns A promise resolving to a ComponentRef for the attached container.
*/
private _attachDialogContainer(overlayRef: OverlayRef, config: MdDialogConfig):
private _attachDialogContainer(overlay: OverlayRef, config: MdDialogConfig):
Promise<ComponentRef<MdDialogContainer>> {
let containerPortal = new ComponentPortal(MdDialogContainer, config.viewContainerRef);
return overlayRef.attach(containerPortal).then(containerRef => {
return overlay.attach(containerPortal).then((containerRef: ComponentRef<MdDialogContainer>) => {
// Pass the config directly to the container so that it can consume any relevant settings.
containerRef.instance.dialogConfig = config;
return containerRef;
Expand All @@ -72,16 +75,18 @@ export class MdDialog {
* Attaches the user-provided component to the already-created MdDialogContainer.
* @param component The type of component being loaded into the dialog.
* @param containerRef Reference to the wrapping MdDialogContainer.
* @param overlayRef Reference to the overlay in which the dialog resides.
* @returns A promise resolving to the MdDialogRef that should be returned to the user.
*/
private _attachDialogContent<T>(
component: ComponentType<T>,
containerRef: ComponentRef<MdDialogContainer>): Promise<MdDialogRef<T>> {
containerRef: ComponentRef<MdDialogContainer>,
overlayRef: OverlayRef): Promise<MdDialogRef<T>> {
let dialogContainer = containerRef.instance;

// Create a reference to the dialog we're creating in order to give the user a handle
// to modify and close it.
let dialogRef = new MdDialogRef();
let dialogRef = new MdDialogRef(overlayRef);

// We create an injector specifically for the component we're instantiating so that it can
// inject the MdDialogRef. This allows a component loaded inside of a dialog to close itself
Expand Down
2 changes: 1 addition & 1 deletion src/demo-app/demo-app/demo-app.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.demo-root {
body {
font-family: Roboto, 'Helvetica Neue', sans-serif;

// Helps fonts on OSX looks more consistent with other systems
Expand Down
5 changes: 3 additions & 2 deletions src/demo-app/demo-app/demo-app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Component} from '@angular/core';
import {Component, ViewEncapsulation} from '@angular/core';
import {ROUTER_DIRECTIVES} from '@angular/router';

import {Dir} from '@angular2-material/core/rtl/dir';
Expand Down Expand Up @@ -32,6 +32,7 @@ export class Home {}
MD_LIST_DIRECTIVES,
MdToolbar,
],
pipes: []
pipes: [],
encapsulation: ViewEncapsulation.None,
})
export class DemoApp { }
4 changes: 4 additions & 0 deletions src/demo-app/dialog/dialog-demo.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
<h1>Dialog demo</h1>

<button (click)="open()" [disabled]="dialogRef">Open dialog</button>

<p>
Last close result: {{lastCloseResult}}
</p>
15 changes: 13 additions & 2 deletions src/demo-app/dialog/dialog-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {OVERLAY_PROVIDERS} from '@angular2-material/core/overlay/overlay';
})
export class DialogDemo {
dialogRef: MdDialogRef<JazzDialog>;
lastCloseResult: string;

constructor(
public dialog: MdDialog,
Expand All @@ -22,13 +23,23 @@ export class DialogDemo {

this.dialog.open(JazzDialog, config).then(ref => {
this.dialogRef = ref;

this.dialogRef.afterClosed().subscribe(result => {
this.lastCloseResult = result;
this.dialogRef = null;
});
});
}
}


@Component({
selector: 'demo-jazz-dialog',
template: `<p>It's Jazz!</p>`
template: `
<p>It's Jazz!</p>
<p><label>How much? <input #howMuch></label></p>
<button type="button" (click)="dialogRef.close(howMuch.value)">Close dialog</button>`
})
export class JazzDialog { }
export class JazzDialog {
constructor(public dialogRef: MdDialogRef<JazzDialog>) { }
}