Skip to content

Commit 57f19cd

Browse files
emilio-martinezandrewseguin
authored andcommitted
feat(dialog): support minWidth, minHeight, maxWidth and maxHeight (#7488)
* 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
1 parent d6698e1 commit 57f19cd

File tree

6 files changed

+104
-4
lines changed

6 files changed

+104
-4
lines changed

src/demo-app/dialog/dialog-demo.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ <h2>Dialog dimensions</h2>
2323
</mat-form-field>
2424
</p>
2525

26+
<p>
27+
<mat-form-field>
28+
<input matInput [(ngModel)]="config.minWidth" placeholder="Min Width">
29+
</mat-form-field>
30+
<mat-form-field>
31+
<input matInput [(ngModel)]="config.minHeight" placeholder="Min Height">
32+
</mat-form-field>
33+
</p>
34+
35+
<p>
36+
<mat-form-field>
37+
<input matInput [(ngModel)]="config.maxWidth" placeholder="Max Width">
38+
</mat-form-field>
39+
<mat-form-field>
40+
<input matInput [(ngModel)]="config.maxHeight" placeholder="Max Height">
41+
</mat-form-field>
42+
</p>
43+
2644
<h2>Dialog position</h2>
2745

2846
<p>

src/demo-app/dialog/dialog-demo.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {Component, Inject, ViewChild, TemplateRef} from '@angular/core';
22
import {DOCUMENT} from '@angular/platform-browser';
3-
import {MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
3+
import {MatDialog, MatDialogConfig, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material';
44

5+
const defaultDialogConfig = new MatDialogConfig();
56

67
@Component({
78
moduleId: module.id,
@@ -21,6 +22,10 @@ export class DialogDemo {
2122
backdropClass: '',
2223
width: '',
2324
height: '',
25+
minWidth: '',
26+
minHeight: '',
27+
maxWidth: defaultDialogConfig.maxWidth,
28+
maxHeight: '',
2429
position: {
2530
top: '',
2631
bottom: '',

src/lib/dialog/dialog-config.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ export class MatDialogConfig {
5757
/** Height of the dialog. */
5858
height?: string = '';
5959

60+
/** Min-width of the dialog. If a number is provided, pixel units are assumed. */
61+
minWidth?: number | string;
62+
63+
/** Min-height of the dialog. If a number is provided, pixel units are assumed. */
64+
minHeight?: number | string;
65+
66+
/** Max-width of the dialog. If a number is provided, pixel units are assumed. Defaults to 80vw */
67+
maxWidth?: number | string = '80vw';
68+
69+
/** Max-height of the dialog. If a number is provided, pixel units are assumed. */
70+
maxHeight?: number | string;
71+
6072
/** Position overrides. */
6173
position?: DialogPosition;
6274

src/lib/dialog/dialog.scss

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
$mat-dialog-padding: 24px !default;
77
$mat-dialog-border-radius: 2px !default;
8-
$mat-dialog-max-width: 80vw !default;
98
$mat-dialog-max-height: 65vh !default;
109
$mat-dialog-button-margin: 8px !default;
1110

@@ -17,7 +16,6 @@ $mat-dialog-button-margin: 8px !default;
1716
border-radius: $mat-dialog-border-radius;
1817
box-sizing: border-box;
1918
overflow: auto;
20-
max-width: $mat-dialog-max-width;
2119
outline: 0;
2220

2321
// The dialog container should completely fill its parent overlay element.

src/lib/dialog/dialog.spec.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,69 @@ describe('MatDialog', () => {
336336
expect(overlayPane.style.height).toBe('100px');
337337
});
338338

339+
it('should should override the min-width of the overlay pane', () => {
340+
dialog.open(PizzaMsg, {
341+
minWidth: '500px'
342+
});
343+
344+
viewContainerFixture.detectChanges();
345+
346+
let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
347+
348+
expect(overlayPane.style.minWidth).toBe('500px');
349+
});
350+
351+
it('should should override the max-width of the overlay pane', fakeAsync(() => {
352+
let dialogRef = dialog.open(PizzaMsg);
353+
354+
viewContainerFixture.detectChanges();
355+
356+
let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
357+
358+
expect(overlayPane.style.maxWidth).toBe('80vw',
359+
'Expected dialog to set a default max-width on overlay pane');
360+
361+
dialogRef.close();
362+
363+
tick(500);
364+
viewContainerFixture.detectChanges();
365+
flushMicrotasks();
366+
367+
dialogRef = dialog.open(PizzaMsg, {
368+
maxWidth: '100px'
369+
});
370+
371+
viewContainerFixture.detectChanges();
372+
373+
overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
374+
375+
expect(overlayPane.style.maxWidth).toBe('100px');
376+
}));
377+
378+
it('should should override the min-height of the overlay pane', () => {
379+
dialog.open(PizzaMsg, {
380+
minHeight: '300px'
381+
});
382+
383+
viewContainerFixture.detectChanges();
384+
385+
let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
386+
387+
expect(overlayPane.style.minHeight).toBe('300px');
388+
});
389+
390+
it('should should override the max-height of the overlay pane', () => {
391+
dialog.open(PizzaMsg, {
392+
maxHeight: '100px'
393+
});
394+
395+
viewContainerFixture.detectChanges();
396+
397+
let overlayPane = overlayContainerElement.querySelector('.cdk-overlay-pane') as HTMLElement;
398+
399+
expect(overlayPane.style.maxHeight).toBe('100px');
400+
});
401+
339402
it('should should override the top offset of the overlay pane', () => {
340403
dialog.open(PizzaMsg, {
341404
position: {

src/lib/dialog/dialog.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,11 @@ export class MatDialog {
190190
scrollStrategy: this._scrollStrategy(),
191191
panelClass: dialogConfig.panelClass,
192192
hasBackdrop: dialogConfig.hasBackdrop,
193-
direction: dialogConfig.direction
193+
direction: dialogConfig.direction,
194+
minWidth: dialogConfig.minWidth,
195+
minHeight: dialogConfig.minHeight,
196+
maxWidth: dialogConfig.maxWidth,
197+
maxHeight: dialogConfig.maxHeight
194198
});
195199

196200
if (dialogConfig.backdropClass) {

0 commit comments

Comments
 (0)