Skip to content

Commit 966cf5f

Browse files
vivian-hu-zzmmalerba
authored andcommitted
fix(grid): fix mat-grid-tile position (#12980)
refresh gapStartIndex and gapEndIndex after move to a new row. Otherwise, they become out of sync and causes wrong calculation.
1 parent 590d294 commit 966cf5f

File tree

3 files changed

+129
-2
lines changed

3 files changed

+129
-2
lines changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,46 @@
1111
</mat-card-content>
1212
</mat-card>
1313

14+
<mat-card>
15+
<mat-card-title>Grid with 1 cell at the beginning of a new row</mat-card-title>
16+
<mat-card-content class="demo-basic-list">
17+
<mat-grid-list [cols]="6" gutterSize="20px" rowHeight="20px">
18+
<mat-grid-tile [colspan]="3" [rowspan]="4"
19+
class="mat-elevation-z15">
20+
</mat-grid-tile>
21+
<mat-grid-tile [colspan]="3" [rowspan]="4"
22+
class="mat-elevation-z15">
23+
</mat-grid-tile>
24+
<mat-grid-tile [colspan]="1" [rowspan]="2"
25+
class="mat-elevation-z15">
26+
</mat-grid-tile>
27+
</mat-grid-list>
28+
</mat-card-content>
29+
</mat-card>
30+
31+
<mat-card>
32+
<mat-card-title>Grid with col-span</mat-card-title>
33+
<mat-card-content class="demo-basic-list">
34+
<mat-grid-list [cols]="10" gutterSize="20px" rowHeight="20px">
35+
<mat-grid-tile [colspan]="4" [rowspan]="4"
36+
class="mat-elevation-z15">
37+
</mat-grid-tile>
38+
<mat-grid-tile [colspan]="2" [rowspan]="2"
39+
class="mat-elevation-z15">
40+
</mat-grid-tile>
41+
<mat-grid-tile [colspan]="4" [rowspan]="4"
42+
class="mat-elevation-z15">
43+
</mat-grid-tile>
44+
<mat-grid-tile [colspan]="4" [rowspan]="4"
45+
class="mat-elevation-z15">
46+
</mat-grid-tile>
47+
<mat-grid-tile [colspan]="4" [rowspan]="4"
48+
class="mat-elevation-z15">
49+
</mat-grid-tile>
50+
</mat-grid-list>
51+
</mat-card-content>
52+
</mat-card>
53+
1454
<mat-card>
1555
<mat-card-title>Fixed-height grid list</mat-card-title>
1656
<mat-card-content>

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

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,65 @@ describe('MatGridList', () => {
246246
expect(getStyle(tiles[3], 'top')).toBe('101px');
247247
});
248248

249+
it('should lay out tiles correctly', () => {
250+
const fixture = createComponent(GridListWithLayout);
251+
252+
fixture.detectChanges();
253+
const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile'));
254+
255+
expect(getStyle(tiles[0], 'width')).toBe('40px');
256+
expect(getStyle(tiles[0], 'height')).toBe('40px');
257+
expect(getComputedLeft(tiles[0])).toBe(0);
258+
expect(getStyle(tiles[0], 'top')).toBe('0px');
259+
260+
expect(getStyle(tiles[1], 'width')).toBe('20px');
261+
expect(getStyle(tiles[1], 'height')).toBe('20px');
262+
expect(getComputedLeft(tiles[1])).toBe(40);
263+
expect(getStyle(tiles[1], 'top')).toBe('0px');
264+
265+
expect(getStyle(tiles[2], 'width')).toBe('40px');
266+
expect(getStyle(tiles[2], 'height')).toBe('40px');
267+
expect(getComputedLeft(tiles[2])).toBe(60);
268+
expect(getStyle(tiles[2], 'top')).toBe('0px');
269+
270+
expect(getStyle(tiles[3], 'width')).toBe('40px');
271+
expect(getStyle(tiles[3], 'height')).toBe('40px');
272+
expect(getComputedLeft(tiles[3])).toBe(0);
273+
expect(getStyle(tiles[3], 'top')).toBe('40px');
274+
275+
expect(getStyle(tiles[4], 'width')).toBe('40px');
276+
expect(getStyle(tiles[4], 'height')).toBe('40px');
277+
expect(getComputedLeft(tiles[4])).toBe(40);
278+
expect(getStyle(tiles[4], 'top')).toBe('40px');
279+
});
280+
281+
it('should lay out tiles correctly when single cell to be placed at the beginning',
282+
() => {
283+
const fixture = createComponent(GridListWithSingleCellAtBeginning);
284+
285+
fixture.detectChanges();
286+
const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile'));
287+
288+
expect(getStyle(tiles[0], 'width')).toBe('40px');
289+
expect(getStyle(tiles[0], 'height')).toBe('40px');
290+
expect(getComputedLeft(tiles[0])).toBe(0);
291+
expect(getStyle(tiles[0], 'top')).toBe('0px');
292+
293+
expect(getStyle(tiles[1], 'width')).toBe('20px');
294+
expect(getStyle(tiles[1], 'height')).toBe('40px');
295+
expect(getComputedLeft(tiles[1])).toBe(40);
296+
expect(getStyle(tiles[1], 'top')).toBe('0px');
297+
298+
expect(getStyle(tiles[2], 'width')).toBe('40px');
299+
expect(getStyle(tiles[2], 'height')).toBe('40px');
300+
expect(getComputedLeft(tiles[2])).toBe(60);
301+
expect(getStyle(tiles[2], 'top')).toBe('0px');
302+
303+
expect(getStyle(tiles[3], 'height')).toBe('20px');
304+
expect(getComputedLeft(tiles[3])).toBe(0);
305+
expect(getStyle(tiles[3], 'top')).toBe('40px');
306+
});
307+
249308
it('should add not add any classes to footers without lines', () => {
250309
const fixture = createComponent(GridListWithFootersWithoutLines);
251310
fixture.detectChanges();
@@ -486,6 +545,29 @@ class GridListWithComplexLayout {
486545
tiles: any[];
487546
}
488547

548+
@Component({template: `
549+
<div style="width:100px">
550+
<mat-grid-list [cols]="10" gutterSize="0px" rowHeight="10px">
551+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
552+
<mat-grid-tile [colspan]="2" [rowspan]="2"></mat-grid-tile>
553+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
554+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
555+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
556+
</mat-grid-list>
557+
</div>`})
558+
class GridListWithLayout {}
559+
560+
@Component({template: `
561+
<div style="width:100px">
562+
<mat-grid-list [cols]="10" gutterSize="0px" rowHeight="10px">
563+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
564+
<mat-grid-tile [colspan]="2" [rowspan]="4"></mat-grid-tile>
565+
<mat-grid-tile [colspan]="4" [rowspan]="4"></mat-grid-tile>
566+
<mat-grid-tile [colspan]="1" [rowspan]="2"></mat-grid-tile>
567+
</mat-grid-list>
568+
</div>`})
569+
class GridListWithSingleCellAtBeginning {}
570+
489571
@Component({template: `
490572
<mat-grid-list cols="1">
491573
<mat-grid-tile>

src/lib/grid-list/tile-coordinator.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ export class TileCoordinator {
9191
// If we've reached the end of the row, go to the next row.
9292
if (this.columnIndex + tileCols > this.tracker.length) {
9393
this._nextRow();
94+
gapStartIndex = this.tracker.indexOf(0, this.columnIndex);
95+
gapEndIndex = this._findGapEndIndex(gapStartIndex);
9496
continue;
9597
}
9698

@@ -99,6 +101,8 @@ export class TileCoordinator {
99101
// If there are no more empty spaces in this row at all, move on to the next row.
100102
if (gapStartIndex == -1) {
101103
this._nextRow();
104+
gapStartIndex = this.tracker.indexOf(0, this.columnIndex);
105+
gapEndIndex = this._findGapEndIndex(gapStartIndex);
102106
continue;
103107
}
104108

@@ -108,8 +112,9 @@ export class TileCoordinator {
108112
// gap on the next iteration.
109113
this.columnIndex = gapStartIndex + 1;
110114

111-
// Continue iterating until we find a gap wide enough for this tile.
112-
} while (gapEndIndex - gapStartIndex < tileCols);
115+
// Continue iterating until we find a gap wide enough for this tile. Since gapEndIndex is
116+
// exclusive, gapEndIndex is 0 means we didn't find a gap and should continue.
117+
} while ((gapEndIndex - gapStartIndex < tileCols) || (gapEndIndex == 0));
113118

114119
// If we still didn't manage to find a gap, ensure that the index is
115120
// at least zero so the tile doesn't get pulled out of the grid.

0 commit comments

Comments
 (0)