Skip to content

Commit 3ce8545

Browse files
committed
Make responsitve grid list
1 parent 1b6b270 commit 3ce8545

File tree

9 files changed

+483
-114
lines changed

9 files changed

+483
-114
lines changed

src/demo-app/grid-list/grid-list-demo.html

Lines changed: 98 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,107 @@
11
<div class="demo-grid-list">
2-
<md-card>
3-
<md-card-title>Basic grid list</md-card-title>
4-
<md-card-content class="demo-basic-list">
5-
<md-grid-list cols="4" [rowHeight]="basicRowHeight">
6-
<md-grid-tile> One </md-grid-tile>
7-
<md-grid-tile> Two </md-grid-tile>
8-
<md-grid-tile> Three </md-grid-tile>
9-
<md-grid-tile> Four </md-grid-tile>
10-
</md-grid-list>
11-
</md-card-content>
12-
</md-card>
2+
<div class="demo-grid-list-fixed">
3+
<md-card>
4+
<md-card-title>Basic grid list</md-card-title>
5+
<md-card-content class="demo-basic-list">
6+
<md-grid-list cols="4" [rowHeight]="basicRowHeight">
7+
<md-grid-tile> One </md-grid-tile>
8+
<md-grid-tile> Two </md-grid-tile>
9+
<md-grid-tile> Three </md-grid-tile>
10+
<md-grid-tile> Four </md-grid-tile>
11+
</md-grid-list>
12+
</md-card-content>
13+
</md-card>
1314

14-
<md-card>
15-
<md-card-title>Fixed-height grid list</md-card-title>
16-
<md-card-content>
17-
<md-grid-list [cols]="fixedCols" [rowHeight]="fixedRowHeight">
18-
<md-grid-tile *ngFor="let tile of tiles" [colspan]="tile.cols" [rowspan]="tile.rows"
19-
[style.background]="tile.color">
20-
{{tile.text}}
21-
</md-grid-tile>
22-
</md-grid-list>
23-
</md-card-content>
24-
<md-card-actions>
25-
<p>Change list cols: <input type="number" [(ngModel)]="fixedCols"></p>
26-
<p>Change row height: <input type="number" [(ngModel)]="fixedRowHeight"></p>
27-
<button md-button (click)="addTileCols()" color="primary">ADD COLSPAN (THREE)</button>
28-
</md-card-actions>
29-
</md-card>
15+
<md-card>
16+
<md-card-title>Fixed-height grid list</md-card-title>
17+
<md-card-content>
18+
<md-grid-list [cols]="fixedCols" [rowHeight]="fixedRowHeight">
19+
<md-grid-tile *ngFor="let tile of tiles" [colspan]="tile.cols" [rowspan]="tile.rows"
20+
[style.background]="tile.color">
21+
{{tile.text}}
22+
</md-grid-tile>
23+
</md-grid-list>
24+
</md-card-content>
25+
<md-card-actions>
26+
<p>Change list cols: <input type="number" [(ngModel)]="fixedCols"></p>
27+
<p>Change row height: <input type="number" [(ngModel)]="fixedRowHeight"></p>
28+
<button md-button (click)="addTileCols()" color="primary">ADD COLSPAN (THREE)</button>
29+
</md-card-actions>
30+
</md-card>
3031

31-
<md-card>
32-
<md-card-title>Ratio-height grid list</md-card-title>
33-
<md-card-content class="demo-ratio-list">
34-
<md-grid-list cols="2" [rowHeight]="ratio" gutterSize="4px">
35-
<md-grid-tile *ngFor="let tile of tiles" [style.background]="'lightblue'">
36-
{{tile.text}}
37-
</md-grid-tile>
38-
</md-grid-list>
39-
</md-card-content>
40-
<md-card-actions>
41-
<p>Change ratio: <input [(ngModel)]="ratio"></p>
42-
</md-card-actions>
43-
</md-card>
32+
<md-card>
33+
<md-card-title>Ratio-height grid list</md-card-title>
34+
<md-card-content class="demo-ratio-list">
35+
<md-grid-list cols="2" [rowHeight]="ratio" gutterSize="4px">
36+
<md-grid-tile *ngFor="let tile of tiles" [style.background]="'lightblue'">
37+
{{tile.text}}
38+
</md-grid-tile>
39+
</md-grid-list>
40+
</md-card-content>
41+
<md-card-actions>
42+
<p>Change ratio: <input [(ngModel)]="ratio"></p>
43+
</md-card-actions>
44+
</md-card>
4445

45-
<md-card>
46-
<md-card-title>Fit-height grid list</md-card-title>
47-
<md-card-content class="demo-fit-list">
48-
<md-grid-list cols="2" rowHeight="fit" [gutterSize]="ratioGutter"
49-
[style.height]="fitListHeight">
50-
<md-grid-tile *ngFor="let tile of tiles" [style.background]="'#F1EBBA'">
51-
{{tile.text}}
52-
</md-grid-tile>
53-
</md-grid-list>
54-
</md-card-content>
55-
<md-card-actions>
56-
<p>Change list height: <input [(ngModel)]="fitListHeight"></p>
57-
<p>Change gutter: <input type="number" [(ngModel)]="ratioGutter"></p>
58-
</md-card-actions>
59-
</md-card>
46+
<md-card>
47+
<md-card-title>Fit-height grid list</md-card-title>
48+
<md-card-content class="demo-fit-list">
49+
<md-grid-list cols="2" rowHeight="fit" [gutterSize]="ratioGutter"
50+
[style.height]="fitListHeight">
51+
<md-grid-tile *ngFor="let tile of tiles" [style.background]="'#F1EBBA'">
52+
{{tile.text}}
53+
</md-grid-tile>
54+
</md-grid-list>
55+
</md-card-content>
56+
<md-card-actions>
57+
<p>Change list height: <input [(ngModel)]="fitListHeight"></p>
58+
<p>Change gutter: <input type="number" [(ngModel)]="ratioGutter"></p>
59+
</md-card-actions>
60+
</md-card>
6061

61-
<md-card>
62-
<md-card-title>Grid list with header</md-card-title>
63-
<md-card-content>
64-
<md-grid-list cols="3" rowHeight="200px">
65-
<md-grid-tile *ngFor="let dog of dogs" style="background:gray">
66-
<md-grid-tile-header>
67-
<md-icon md-grid-avatar>info_outline</md-icon>
68-
{{dog.name}}
69-
</md-grid-tile-header>
70-
</md-grid-tile>
71-
</md-grid-list>
72-
</md-card-content>
73-
</md-card>
62+
<md-card>
63+
<md-card-title>Grid list with header</md-card-title>
64+
<md-card-content>
65+
<md-grid-list cols="3" rowHeight="200px">
66+
<md-grid-tile *ngFor="let dog of dogs" style="background:gray">
67+
<md-grid-tile-header>
68+
<md-icon md-grid-avatar>info_outline</md-icon>
69+
{{dog.name}}
70+
</md-grid-tile-header>
71+
</md-grid-tile>
72+
</md-grid-list>
73+
</md-card-content>
74+
</md-card>
7475

75-
<md-card>
76-
<md-card-title>Grid list with footer</md-card-title>
77-
<md-card-content>
78-
<md-grid-list cols="3" rowHeight="200px">
79-
<md-grid-tile *ngFor="let dog of dogs">
80-
<img [alt]="dog.name" src="https://material.angularjs.org/material2_assets/ngconf/{{dog.name}}.png">
81-
<md-grid-tile-footer>
82-
<h3 md-line>{{dog.name}}</h3>
83-
<span md-line>Human: {{dog.human}}</span>
84-
<md-icon>star_border</md-icon>
85-
</md-grid-tile-footer>
76+
<md-card>
77+
<md-card-title>Grid list with footer</md-card-title>
78+
<md-card-content>
79+
<md-grid-list cols="3" rowHeight="200px">
80+
<md-grid-tile *ngFor="let dog of dogs">
81+
<img [alt]="dog.name" src="https://material.angularjs.org/material2_assets/ngconf/{{dog.name}}.png">
82+
<md-grid-tile-footer>
83+
<h3 md-line>{{dog.name}}</h3>
84+
<span md-line>Human: {{dog.human}}</span>
85+
<md-icon>star_border</md-icon>
86+
</md-grid-tile-footer>
87+
</md-grid-tile>
88+
</md-grid-list>
89+
</md-card-content>
90+
</md-card>
91+
92+
</div>
93+
94+
<div class="demo-grid-list-responsive">
95+
<md-card>
96+
<md-grid-list gutterSize="4px" rowHeight="4:3"
97+
[responsiveGutterSize]="{'gt-md': '16px', 'gt-sm': '8px'}"
98+
[responsiveCols]="{'gt-md': '12', 'xs': '3', 'gt-xs': '8'}"
99+
[responsiveRowHeight]="{'gt-md': '1:1'}">
100+
<md-grid-tile *ngFor="let tile of colorTiles" [style.background]="tile.color"
101+
[responsiveColspan]="{'gt-md': tile.colspan, 'gt-xs': tile.smallColspan}"
102+
[responsiveRowspan]="{'gt-md': tile.rowspan, 'gt-xs': tile.smallRowspan}">
86103
</md-grid-tile>
87104
</md-grid-list>
88-
</md-card-content>
89-
</md-card>
105+
</md-card>
106+
</div>
90107
</div>
91-

src/demo-app/grid-list/grid-list-demo.scss

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
12
.demo-grid-list {
2-
width: 1100px;
3+
.demo-grid-list-fixed {
4+
width: 1100px;
5+
}
36

47
.mat-card {
58
margin: 16px 0;

src/demo-app/grid-list/grid-list-demo.ts

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,66 @@ export class GridListDemo {
3232
ratio = '4:1';
3333

3434
addTileCols() { this.tiles[2].cols++; }
35+
36+
colors = [
37+
'#ffebee', '#ffcdd2', '#ef9a9a', '#e57373', '#ef5350', '#f44336', '#e53935', '#d32f2f',
38+
'#c62828', '#b71c1c', '#ff8a80', '#ff5252', '#ff1744', '#d50000', '#f8bbd0', '#f48fb1',
39+
'#f06292', '#ec407a', '#e91e63', '#d81b60', '#c2185b', '#ad1457', '#880e4f', '#ff80ab',
40+
'#ff4081', '#f50057', '#c51162', '#e1bee7', '#ce93d8', '#ba68c8', '#ab47bc', '#9c27b0',
41+
'#8e24aa', '#7b1fa2', '#4a148c', '#ea80fc', '#e040fb', '#d500f9', '#aa00ff', '#ede7f6',
42+
'#d1c4e9', '#b39ddb', '#9575cd', '#7e57c2', '#673ab7', '#5e35b1', '#4527a0', '#311b92',
43+
'#b388ff', '#7c4dff', '#651fff', '#6200ea', '#c5cae9', '#9fa8da', '#7986cb', '#5c6bc0',
44+
'#3f51b5', '#3949ab', '#303f9f', '#283593', '#1a237e', '#8c9eff', '#536dfe', '#3d5afe',
45+
'#304ffe', '#e3f2fd', '#bbdefb', '#90caf9', '#64b5f6', '#42a5f5', '#2196f3', '#1e88e5',
46+
'#1976d2', '#1565c0', '#0d47a1', '#82b1ff', '#448aff', '#2979ff', '#2962ff', '#b3e5fc',
47+
'#81d4fa', '#4fc3f7', '#29b6f6', '#03a9f4', '#039be5', '#0288d1', '#0277bd', '#01579b',
48+
'#80d8ff', '#40c4ff', '#00b0ff', '#0091ea', '#e0f7fa', '#b2ebf2', '#80deea', '#4dd0e1',
49+
'#26c6da', '#00bcd4', '#00acc1', '#0097a7', '#00838f', '#006064', '#84ffff', '#18ffff',
50+
'#00e5ff', '#00b8d4', '#e0f2f1', '#b2dfdb', '#80cbc4', '#4db6ac', '#26a69a', '#009688',
51+
'#00897b', '#00796b', '#00695c', '#a7ffeb', '#64ffda', '#1de9b6', '#00bfa5', '#e8f5e9',
52+
'#c8e6c9', '#a5d6a7', '#81c784', '#66bb6a', '#4caf50', '#43a047', '#388e3c', '#2e7d32',
53+
'#1b5e20', '#b9f6ca', '#69f0ae', '#00e676', '#00c853', '#f1f8e9', '#dcedc8', '#c5e1a5',
54+
'#aed581', '#9ccc65', '#8bc34a', '#7cb342', '#689f38', '#558b2f', '#33691e', '#ccff90',
55+
'#b2ff59', '#76ff03', '#64dd17', '#f9fbe7', '#f0f4c3', '#e6ee9c', '#dce775', '#d4e157',
56+
'#cddc39', '#c0ca33', '#afb42b', '#9e9d24', '#827717', '#f4ff81', '#eeff41', '#c6ff00',
57+
'#aeea00', '#fffde7', '#fff9c4', '#fff59d', '#fff176', '#ffee58', '#ffeb3b', '#fdd835',
58+
'#fbc02d', '#f9a825', '#f57f17', '#ffff8d', '#ffff00', '#ffea00', '#ffd600', '#fff8e1',
59+
'#ffecb3', '#ffe082', '#ffd54f', '#ffca28', '#ffc107', '#ffb300', '#ffa000', '#ff8f00',
60+
'#ff6f00', '#ffe57f', '#ffd740', '#ffc400', '#ffab00', '#fff3e0', '#ffe0b2', '#ffcc80',
61+
'#ffb74d', '#ffa726', '#ff9800', '#fb8c00', '#f57c00', '#ef6c00', '#e65100', '#ffd180',
62+
'#ffab40', '#ff9100', '#ff6d00', '#fbe9e7', '#ffccbc', '#ffab91', '#ff8a65', '#ff7043',
63+
'#ff5722', '#f4511e', '#e64a19', '#d84315', '#bf360c', '#ff9e80', '#ff6e40', '#ff3d00',
64+
'#dd2c00', '#d7ccc8', '#bcaaa4', '#795548', '#d7ccc8', '#bcaaa4', '#8d6e63', '#eceff1',
65+
'#cfd8dc', '#b0bec5', '#90a4ae', '#78909c', '#607d8b', '#546e7a', '#cfd8dc', '#b0bec5',
66+
'#78909c'];
67+
colorTiles = this.generateTiles();
68+
69+
generateTiles() {
70+
var tiles = [];
71+
for (var i = 0; i < 46; i++) {
72+
tiles.push({
73+
color: this.randomColor(),
74+
colspan: this.randomSpan(),
75+
rowspan: this.randomSpan(),
76+
smallRowspan: this.randomSpan(),
77+
smallColspan: this.randomSpan(),
78+
});
79+
}
80+
return tiles;
81+
}
82+
83+
randomColor() {
84+
return this.colors[Math.floor(Math.random() * this.colors.length)];
85+
}
86+
87+
randomSpan() {
88+
var r = Math.random();
89+
if (r < 0.8) {
90+
return 1;
91+
} else if (r < 0.9) {
92+
return 2;
93+
} else {
94+
return 3;
95+
}
96+
}
3597
}

src/lib/grid-list/grid-list.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,42 @@ It is possible to set the rowspan and colspan of each `md-grid-tile` individuall
3737
exceed the number of `cols` in the `md-grid-list`. There is no such restriction on the `rowspan`
3838
however, more rows will simply be added for it the tile to fill.
3939

40+
### Responsive number of columns, row height, and gutter size
41+
42+
`window.matchMedia` is used to evaluate whether a given media query is true or false given the
43+
current device's screen / window size. The media query will be re-evaluated on resize.
44+
45+
Grid list has pre-programmed support for media queries that match the layout breakpoints:
46+
47+
#### Breakpoints
48+
| Breakpoint | mediaQuery |
49+
|------------|---------------------------------------------|
50+
| xs | (max-width: 599px) |
51+
| gt-xs | (min-width: 600px) |
52+
| sm | (min-width: 600px) and (max-width: 959px) |
53+
| gt-sm | (min-width: 960px) |
54+
| md | (min-width: 960px) and (max-width: 1279px) |
55+
| gt-md | (min-width: 1280px) |
56+
| lg | (min-width: 1280px) and (max-width: 1919px) |
57+
| gt-lg | (min-width: 1920px) |
58+
| xl | (min-width: 1920px) |
59+
| landscape | landscape |
60+
| portrait | portrait |
61+
| print | print |
62+
63+
See Material Design's Layout - [Adaptive UI][0] for more details.
64+
65+
#### Usage
66+
```html
67+
<md-grid-list gutterSize="4px" rowHeight="4:3"
68+
[responsiveGutterSize]="{'gt-md': '16px', 'gt-sm': '8px'}"
69+
[responsiveCols]="{'gt-md': '12', 'xs': '3', 'gt-xs': '8'}"
70+
[responsiveRowHeight]="{'gt-md': '1:1'}">
71+
<md-grid-tile *ngFor="let tile of colorTiles" [style.background]="tile.color">
72+
</md-grid-tile>
73+
</md-grid-list>
74+
```
75+
4076
### Tile headers and footers
4177

4278
A header and footer can be added to an `md-grid-tile` using the `md-grid-tile-header` and
@@ -50,3 +86,5 @@ accessibility treatment based on the specific workflow of your application.
5086

5187
If the grid-list is used to present a list of _non-interactive_ content items, then the grid-list
5288
element should be given `role="list"` and each tile should be given `role="listitem"`.
89+
90+
[0]: https://material.io/guidelines/layout/responsive-ui.html

src/lib/grid-list/grid-list.spec.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import {async, TestBed} from '@angular/core/testing';
1+
import {async, fakeAsync, TestBed, tick} from '@angular/core/testing';
2+
import {dispatchFakeEvent} from '@angular/cdk/testing';
23
import {Component, DebugElement} from '@angular/core';
34
import {By} from '@angular/platform-browser';
45
import {MdGridList, MdGridListModule} from './index';
@@ -28,6 +29,7 @@ describe('MdGridList', () => {
2829
GridListWithComplexLayout,
2930
GridListWithFootersWithoutLines,
3031
GridListWithFooterContainingTwoLines,
32+
GridListWithResponsiveValues,
3133
],
3234
});
3335

@@ -265,6 +267,17 @@ describe('MdGridList', () => {
265267
expect(firstTile.style.marginTop).toBe('0px');
266268
expect(firstTile.style.left).toBe('0px');
267269
});
270+
271+
it('should get correct responsive values', fakeAsync(() => {
272+
let fixture = TestBed.createComponent(GridListWithResponsiveValues);
273+
let gridListElement = fixture.debugElement.query(By.directive(MdGridList));
274+
let gridListInstance = gridListElement.injector.get<MdGridList>(MdGridList);
275+
276+
fixture.detectChanges();
277+
278+
expect(gridListInstance.cols).toBe(3, 'Expect cols number to use md');
279+
expect(gridListInstance.gutterSize).toBe('3px', 'Expect gutter size use sm');
280+
}));
268281
});
269282

270283

@@ -436,3 +449,20 @@ class GridListWithFootersWithoutLines { }
436449
</md-grid-tile>
437450
</md-grid-list>`})
438451
class GridListWithFooterContainingTwoLines { }
452+
453+
@Component({template: `
454+
<md-grid-list [responsiveCols]="responsiveCols"
455+
[responsiveGutterSize]="responsiveGutterSize"
456+
[responsiveRowHeight]="responsiveRowHeight">
457+
<md-grid-tile *ngFor="let tile of tiles" [colspan]="tile.cols" [rowspan]="tile.rows"
458+
[style.background]="tile.color">
459+
{{tile.text}}
460+
</md-grid-tile>
461+
</md-grid-list>
462+
`})
463+
class GridListWithResponsiveValues {
464+
responsiveCols = {'sm': 1, 'md': '3', 'lg': '8'};
465+
responsiveGutterSize = {'sm': '1px', 'gt-sm': '3px', 'lg': '5px'};
466+
responsiveRowHeight = {'sm': '100px', 'gt-sm': '1:1'};
467+
tiles: any[];
468+
}

0 commit comments

Comments
 (0)