From 57f19cd086bde26724b6430c63baacd1f835380a Mon Sep 17 00:00:00 2001 From: Emilio Date: Mon, 9 Oct 2017 15:50:21 -0700 Subject: [PATCH] feat(dialog): support minWidth, minHeight, maxWidth and maxHeight (#7488) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(dialog): support minWidth, minHeight, maxWidth and maxHeight * Adds Dialog support for `minWidth`, `minHeight`, `maxWidth` and `maxHeight` via config. Mostly delegates to Overlay. * Moves declared `max-width` on `. mat-dialog-container` stylesheet to be authored via `MatDialogConfig`, providing the same default `80vw` value. Without this change, there would likely be undesired layout results due to different constraints being set on the overlay container vs the nested the dialog container. * Added note on `minHeight` and `maxHeight` regarding the potential need to also set a `height` due to the rules around computed height resolution (https://www.w3.org/TR/CSS2/visudet.html#min-max-widths). Any value set on `height` as a default would probably be assuming too much and may have varying results across browsers. * test(dialog): add tests for minWidth, minHeight, maxWidth and maxHeight * demo(dialog): add fields for minWidth, minHeight, maxWidth and maxHeight Not adding `minWidth`, `minHeight`, `maxWidth` and `maxHeight` to `config` to avoid overriding the default value of `maxWidth` particularly—the type checker will require it to be a string. Instead, setting `config` to type `MatDialogConfig` is prefered to appease the type checker since those four properties are optional. * demo(dialog): address AOT issues Appeases the AOT type checker for the template by extending `MatDialogConfig` to disallow `position` from being undefined, given that it’s optional. Guards cannot be set on the template because the values are bound to NgModel. * chore(dialog): address feedback regarding over-verbose comments * fix(dialog): address feedback to not initialize some dialog config props * demo(dialog): set init values for minWidth, minHeight, maxWidth and maxHeight * chore(dialog): allow number|string for min/max widths and heights --- src/demo-app/dialog/dialog-demo.html | 18 ++++++++ src/demo-app/dialog/dialog-demo.ts | 7 +++- src/lib/dialog/dialog-config.ts | 12 ++++++ src/lib/dialog/dialog.scss | 2 - src/lib/dialog/dialog.spec.ts | 63 ++++++++++++++++++++++++++++ src/lib/dialog/dialog.ts | 6 ++- 6 files changed, 104 insertions(+), 4 deletions(-) diff --git a/src/demo-app/dialog/dialog-demo.html b/src/demo-app/dialog/dialog-demo.html index ffceaaae13bf..b54508cf30b0 100644 --- a/src/demo-app/dialog/dialog-demo.html +++ b/src/demo-app/dialog/dialog-demo.html @@ -23,6 +23,24 @@

Dialog dimensions

+

+ + + + + + +

+ +

+ + + + + + +

+

Dialog position

diff --git a/src/demo-app/dialog/dialog-demo.ts b/src/demo-app/dialog/dialog-demo.ts index 87c67b151e18..1895b6e31f48 100644 --- a/src/demo-app/dialog/dialog-demo.ts +++ b/src/demo-app/dialog/dialog-demo.ts @@ -1,7 +1,8 @@ import {Component, Inject, ViewChild, TemplateRef} from '@angular/core'; import {DOCUMENT} from '@angular/platform-browser'; -import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; +import {MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material'; +const defaultDialogConfig = new MatDialogConfig(); @Component({ moduleId: module.id, @@ -21,6 +22,10 @@ export class DialogDemo { backdropClass: '', width: '', height: '', + minWidth: '', + minHeight: '', + maxWidth: defaultDialogConfig.maxWidth, + maxHeight: '', position: { top: '', bottom: '', diff --git a/src/lib/dialog/dialog-config.ts b/src/lib/dialog/dialog-config.ts index 424bec9e84ab..7f6f47d42da4 100644 --- a/src/lib/dialog/dialog-config.ts +++ b/src/lib/dialog/dialog-config.ts @@ -57,6 +57,18 @@ export class MatDialogConfig { /** Height of the dialog. */ height?: string = ''; + /** Min-width of the dialog. If a number is provided, pixel units are assumed. */ + minWidth?: number | string; + + /** Min-height of the dialog. If a number is provided, pixel units are assumed. */ + minHeight?: number | string; + + /** Max-width of the dialog. If a number is provided, pixel units are assumed. Defaults to 80vw */ + maxWidth?: number | string = '80vw'; + + /** Max-height of the dialog. If a number is provided, pixel units are assumed. */ + maxHeight?: number | string; + /** Position overrides. */ position?: DialogPosition; diff --git a/src/lib/dialog/dialog.scss b/src/lib/dialog/dialog.scss index 2f04aec0b4cb..4a72cc903a01 100644 --- a/src/lib/dialog/dialog.scss +++ b/src/lib/dialog/dialog.scss @@ -5,7 +5,6 @@ $mat-dialog-padding: 24px !default; $mat-dialog-border-radius: 2px !default; -$mat-dialog-max-width: 80vw !default; $mat-dialog-max-height: 65vh !default; $mat-dialog-button-margin: 8px !default; @@ -17,7 +16,6 @@ $mat-dialog-button-margin: 8px !default; border-radius: $mat-dialog-border-radius; box-sizing: border-box; overflow: auto; - max-width: $mat-dialog-max-width; outline: 0; // The dialog container should completely fill its parent overlay element. diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts index 1ce22f92d319..4d4b0fde7242 100644 --- a/src/lib/dialog/dialog.spec.ts +++ b/src/lib/dialog/dialog.spec.ts @@ -336,6 +336,69 @@ describe('MatDialog', () => { expect(overlayPane.style.height).toBe('100px'); }); + it('should should override the min-width of the overlay pane', () => { + dialog.open(PizzaMsg, { + minWidth: '500px' + }); + + viewContainerFixture.detectChanges(); + + let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.minWidth).toBe('500px'); + }); + + it('should should override the max-width of the overlay pane', fakeAsync(() => { + let dialogRef = dialog.open(PizzaMsg); + + viewContainerFixture.detectChanges(); + + let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.maxWidth).toBe('80vw', + 'Expected dialog to set a default max-width on overlay pane'); + + dialogRef.close(); + + tick(500); + viewContainerFixture.detectChanges(); + flushMicrotasks(); + + dialogRef = dialog.open(PizzaMsg, { + maxWidth: '100px' + }); + + viewContainerFixture.detectChanges(); + + overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.maxWidth).toBe('100px'); + })); + + it('should should override the min-height of the overlay pane', () => { + dialog.open(PizzaMsg, { + minHeight: '300px' + }); + + viewContainerFixture.detectChanges(); + + let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.minHeight).toBe('300px'); + }); + + it('should should override the max-height of the overlay pane', () => { + dialog.open(PizzaMsg, { + maxHeight: '100px' + }); + + viewContainerFixture.detectChanges(); + + let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement; + + expect(overlayPane.style.maxHeight).toBe('100px'); + }); + it('should should override the top offset of the overlay pane', () => { dialog.open(PizzaMsg, { position: { diff --git a/src/lib/dialog/dialog.ts b/src/lib/dialog/dialog.ts index 54d358c8556e..f9a370ea8ff1 100644 --- a/src/lib/dialog/dialog.ts +++ b/src/lib/dialog/dialog.ts @@ -190,7 +190,11 @@ export class MatDialog { scrollStrategy: this._scrollStrategy(), panelClass: dialogConfig.panelClass, hasBackdrop: dialogConfig.hasBackdrop, - direction: dialogConfig.direction + direction: dialogConfig.direction, + minWidth: dialogConfig.minWidth, + minHeight: dialogConfig.minHeight, + maxWidth: dialogConfig.maxWidth, + maxHeight: dialogConfig.maxHeight }); if (dialogConfig.backdropClass) {