From 15c082381090e271c56f6854317d1c1ea7c7217a Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 26 Dec 2017 14:23:48 +0200 Subject: [PATCH] fix(grid-list): tile being pulled outside the grid if no gap can be found Fixes and issue in the grid list where a tile, for which we couldn't find a gap in which to put it, is being pulled outside the grid due to the index defaulting to -1. Fixes #4515. --- src/lib/grid-list/grid-list.spec.ts | 22 +++++++++++++++++++++- src/lib/grid-list/tile-coordinator.ts | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/lib/grid-list/grid-list.spec.ts b/src/lib/grid-list/grid-list.spec.ts index 4ccf274839a8..17f956dfc79b 100644 --- a/src/lib/grid-list/grid-list.spec.ts +++ b/src/lib/grid-list/grid-list.spec.ts @@ -28,6 +28,7 @@ describe('MatGridList', () => { GridListWithComplexLayout, GridListWithFootersWithoutLines, GridListWithFooterContainingTwoLines, + GridListWithoutMatchingGap, ], }); @@ -287,6 +288,15 @@ describe('MatGridList', () => { expect(getStyle(tile, 'height')).toBe('400px'); }); + it('should ensure that all tiles are inside the grid when there are no matching gaps', () => { + const fixture = TestBed.createComponent(GridListWithoutMatchingGap); + const tiles = fixture.debugElement.queryAll(By.css('mat-grid-tile')); + + fixture.detectChanges(); + expect(tiles.every(tile => getComputedLeft(tile) >= 0)) + .toBe(true, 'Expected none of the tiles to have a negative `left`'); + }); + }); @@ -298,7 +308,7 @@ function getStyle(el: DebugElement, prop: string): string { function getComputedLeft(element: DebugElement): number { // While the other properties in this test use `getComputedStyle`, we use `getBoundingClientRect` // for left because iOS Safari doesn't support using `getComputedStyle` to get the calculated - // `left` balue when using CSS `calc`. We subtract the `left` of the document body because + // `left` value when using CSS `calc`. We subtract the `left` of the document body because // browsers, by default, add a margin to the body (typically 8px). let elementRect = element.nativeElement.getBoundingClientRect(); let bodyRect = document.body.getBoundingClientRect(); @@ -458,3 +468,13 @@ class GridListWithFootersWithoutLines { } `}) class GridListWithFooterContainingTwoLines { } + +@Component({template: ` + + 1 + 2 + 3 + 4 + +`}) +class GridListWithoutMatchingGap { } diff --git a/src/lib/grid-list/tile-coordinator.ts b/src/lib/grid-list/tile-coordinator.ts index 841dd7780d64..ce49d954bc42 100644 --- a/src/lib/grid-list/tile-coordinator.ts +++ b/src/lib/grid-list/tile-coordinator.ts @@ -108,7 +108,10 @@ export class TileCoordinator { // Continue iterating until we find a gap wide enough for this tile. } while (gapEndIndex - gapStartIndex < tileCols); - return gapStartIndex; + + // If we still didn't manage to find a gap, ensure that the index is + // at least zero so the tile doesn't get pulled out of the grid. + return Math.max(gapStartIndex, 0); } /** Move "down" to the next row. */