mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(grid-list): incorrectly laying out tiles for nested list (#13086)
Fixes the grid list picking up the tiles of other nested grid lists, causing them to not being laid out correctly. Fixes #13074.
This commit is contained in:
committed by
vivian-hu
parent
3c55caaf1e
commit
3e1cff0618
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google LLC All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {InjectionToken} from '@angular/core';
|
||||
|
||||
/**
|
||||
* Injection token used to provide a grid list to a tile and to avoid circular imports.
|
||||
* @docs-private
|
||||
*/
|
||||
export const MAT_GRID_LIST = new InjectionToken<MatGridListBase>('MAT_GRID_LIST');
|
||||
|
||||
/**
|
||||
* Base interface for a `MatGridList`.
|
||||
* @docs-private
|
||||
*/
|
||||
export interface MatGridListBase {
|
||||
cols: number;
|
||||
gutterSize: string;
|
||||
rowHeight: number | string;
|
||||
}
|
||||
@@ -139,6 +139,18 @@ describe('MatGridList', () => {
|
||||
expect(getStyle(tiles[2], 'top')).toBe('101px');
|
||||
});
|
||||
|
||||
it('should lay out the tiles correctly for a nested grid list', () => {
|
||||
const fixture = createComponent(NestedGridList);
|
||||
fixture.detectChanges();
|
||||
|
||||
const innerTiles = fixture.debugElement.queryAll(
|
||||
By.css('mat-grid-tile mat-grid-list mat-grid-tile'));
|
||||
|
||||
expect(getStyle(innerTiles[0], 'top')).toBe('0px');
|
||||
expect(getStyle(innerTiles[1], 'top')).toBe('101px');
|
||||
expect(getStyle(innerTiles[2], 'top')).toBe('202px');
|
||||
});
|
||||
|
||||
it('should set the gutter size if passed', () => {
|
||||
const fixture = createComponent(GridListWithGutterSize);
|
||||
fixture.detectChanges();
|
||||
@@ -635,3 +647,19 @@ class GridListWithRtl { }
|
||||
`
|
||||
})
|
||||
class GridListWithIndirectTileDescendants {}
|
||||
|
||||
|
||||
@Component({template: `
|
||||
<div style="width:200px">
|
||||
<mat-grid-list cols="2" rowHeight="100px">
|
||||
<mat-grid-tile></mat-grid-tile>
|
||||
<mat-grid-tile>
|
||||
<mat-grid-list cols="1" rowHeight="100px">
|
||||
<mat-grid-tile></mat-grid-tile>
|
||||
<mat-grid-tile></mat-grid-tile>
|
||||
<mat-grid-tile></mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
</div>`})
|
||||
class NestedGridList { }
|
||||
|
||||
@@ -23,6 +23,7 @@ import {TileCoordinator} from './tile-coordinator';
|
||||
import {TileStyler, FitTileStyler, RatioTileStyler, FixedTileStyler} from './tile-styler';
|
||||
import {Directionality} from '@angular/cdk/bidi';
|
||||
import {coerceNumberProperty} from '@angular/cdk/coercion';
|
||||
import {MAT_GRID_LIST, MatGridListBase} from './grid-list-base';
|
||||
|
||||
|
||||
// TODO(kara): Conditional (responsive) column count / row size.
|
||||
@@ -40,10 +41,14 @@ const MAT_FIT_MODE = 'fit';
|
||||
host: {
|
||||
'class': 'mat-grid-list',
|
||||
},
|
||||
providers: [{
|
||||
provide: MAT_GRID_LIST,
|
||||
useExisting: MatGridList
|
||||
}],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
export class MatGridList implements OnInit, AfterContentChecked {
|
||||
export class MatGridList implements MatGridListBase, OnInit, AfterContentChecked {
|
||||
/** Number of columns being rendered. */
|
||||
private _cols: number;
|
||||
|
||||
@@ -139,16 +144,18 @@ export class MatGridList implements OnInit, AfterContentChecked {
|
||||
/** Computes and applies the size and position for all children grid tiles. */
|
||||
private _layoutTiles(): void {
|
||||
if (!this._tileCoordinator) {
|
||||
this._tileCoordinator = new TileCoordinator(this._tiles);
|
||||
this._tileCoordinator = new TileCoordinator();
|
||||
}
|
||||
|
||||
|
||||
const tracker = this._tileCoordinator;
|
||||
const tiles = this._tiles.filter(tile => !tile._gridList || tile._gridList === this);
|
||||
const direction = this._dir ? this._dir.value : 'ltr';
|
||||
|
||||
this._tileCoordinator.update(this.cols);
|
||||
this._tileCoordinator.update(this.cols, tiles);
|
||||
this._tileStyler.init(this.gutterSize, tracker, this.cols, direction);
|
||||
|
||||
this._tiles.forEach((tile, index) => {
|
||||
tiles.forEach((tile, index) => {
|
||||
const pos = tracker.positions[index];
|
||||
this._tileStyler.setStyle(tile, pos.row, pos.col);
|
||||
});
|
||||
|
||||
@@ -11,14 +11,17 @@ import {
|
||||
ViewEncapsulation,
|
||||
ElementRef,
|
||||
Input,
|
||||
Optional,
|
||||
ContentChildren,
|
||||
QueryList,
|
||||
AfterContentInit,
|
||||
Directive,
|
||||
ChangeDetectionStrategy,
|
||||
Inject,
|
||||
} from '@angular/core';
|
||||
import {MatLine, MatLineSetter} from '@angular/material/core';
|
||||
import {coerceNumberProperty} from '@angular/cdk/coercion';
|
||||
import {MAT_GRID_LIST, MatGridListBase} from './grid-list-base';
|
||||
|
||||
@Component({
|
||||
moduleId: module.id,
|
||||
@@ -36,7 +39,9 @@ export class MatGridTile {
|
||||
_rowspan: number = 1;
|
||||
_colspan: number = 1;
|
||||
|
||||
constructor(private _element: ElementRef<HTMLElement>) {}
|
||||
constructor(
|
||||
private _element: ElementRef<HTMLElement>,
|
||||
@Optional() @Inject(MAT_GRID_LIST) public _gridList?: MatGridListBase) {}
|
||||
|
||||
/** Amount of rows that the grid tile takes up. */
|
||||
@Input()
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {QueryList} from '@angular/core';
|
||||
import {MatGridTile} from './grid-tile';
|
||||
|
||||
/**
|
||||
@@ -53,19 +52,17 @@ export class TileCoordinator {
|
||||
/** The computed (row, col) position of each tile (the output). */
|
||||
positions: TilePosition[];
|
||||
|
||||
constructor(private _tiles: QueryList<MatGridTile>) {}
|
||||
|
||||
/**
|
||||
* Updates the tile positions.
|
||||
* @param numColumns Amount of columns in the grid.
|
||||
*/
|
||||
update(numColumns: number) {
|
||||
update(numColumns: number, tiles: MatGridTile[]) {
|
||||
this.columnIndex = 0;
|
||||
this.rowIndex = 0;
|
||||
|
||||
this.tracker = new Array(numColumns);
|
||||
this.tracker.fill(0, 0, this.tracker.length);
|
||||
this.positions = this._tiles.map(tile => this._trackTile(tile));
|
||||
this.positions = tiles.map(tile => this._trackTile(tile));
|
||||
}
|
||||
|
||||
/** Calculates the row and col position of a tile. */
|
||||
|
||||
Reference in New Issue
Block a user