Skip to content

Commit

Permalink
fix(grid-list): styles not cleared when switching to a different styl…
Browse files Browse the repository at this point in the history
…ing mode

Fixes the old styles not being cleared when switching between styling modes in the grid list (e.g. going for proportions to a fixed height).

Fixes #4047.
  • Loading branch information
crisbeto committed Aug 27, 2017
1 parent ec4ea06 commit 4250594
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 19 deletions.
30 changes: 26 additions & 4 deletions src/lib/grid-list/grid-list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ describe('MdGridList', () => {
it('should use a ratio row height if passed in', () => {
let fixture = TestBed.createComponent(GirdListWithRowHeightRatio);

fixture.componentInstance.heightRatio = '4:1';
fixture.componentInstance.rowHeight = '4:1';
fixture.detectChanges();

let tile = fixture.debugElement.query(By.directive(MdGridTile));
expect(getStyle(tile, 'padding-top')).toBe('100px');

fixture.componentInstance.heightRatio = '2:1';
fixture.componentInstance.rowHeight = '2:1';
fixture.detectChanges();

expect(getStyle(tile, 'padding-top')).toBe('200px');
Expand Down Expand Up @@ -253,6 +253,28 @@ describe('MdGridList', () => {
let footer = fixture.debugElement.query(By.directive(MdGridTileText));
expect(footer.nativeElement.classList.contains('mat-2-line')).toBe(true);
});

it('should reset the old styles when switching to a new tile styler', () => {
const fixture = TestBed.createComponent(GirdListWithRowHeightRatio);

fixture.componentInstance.rowHeight = '4:1';
fixture.detectChanges();

const list = fixture.debugElement.query(By.directive(MdGridList));
const tile = fixture.debugElement.query(By.directive(MdGridTile));

expect(getStyle(tile, 'padding-top')).toBe('100px');
expect(getStyle(list, 'padding-bottom')).toBe('100px');

fixture.componentInstance.rowHeight = '400px';
fixture.detectChanges();

expect(getStyle(tile, 'padding-top')).toBe('0px', 'Expected tile padding to be reset.');
expect(getStyle(list, 'padding-bottom')).toBe('0px', 'Expected list padding to be reset.');
expect(getStyle(tile, 'top')).toBe('0px');
expect(getStyle(tile, 'height')).toBe('400px');
});

});


Expand Down Expand Up @@ -294,12 +316,12 @@ class GridListWithUnspecifiedRowHeight { }

@Component({template: `
<div style="width:400px">
<md-grid-list cols="1" [rowHeight]="heightRatio">
<md-grid-list cols="1" [rowHeight]="rowHeight">
<md-grid-tile></md-grid-tile>
</md-grid-list>
</div>`})
class GirdListWithRowHeightRatio {
heightRatio: string;
rowHeight: string;
}

@Component({template: `
Expand Down
34 changes: 21 additions & 13 deletions src/lib/grid-list/grid-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,12 @@ export class MdGridList implements OnInit, AfterContentChecked {
/** Set internal representation of row height from the user-provided value. */
@Input()
set rowHeight(value: string | number) {
this._rowHeight = coerceToString(value);
this._setTileStyler();
const newValue = coerceToString(value);

if (newValue !== this._rowHeight) {
this._rowHeight = newValue;
this._setTileStyler(this._rowHeight);
}
}

ngOnInit() {
Expand All @@ -106,44 +110,48 @@ export class MdGridList implements OnInit, AfterContentChecked {
private _checkCols() {
if (!this.cols) {
throw Error(`md-grid-list: must pass in number of columns. ` +
`Example: <md-grid-list cols="3">`);
`Example: <md-grid-list cols="3">`);
}
}

/** Default to equal width:height if rowHeight property is missing */
private _checkRowHeight(): void {
if (!this._rowHeight) {
this._tileStyler = new RatioTileStyler('1:1');
this._setTileStyler('1:1');
}
}

/** Creates correct Tile Styler subtype based on rowHeight passed in by user */
private _setTileStyler(): void {
if (this._rowHeight === MD_FIT_MODE) {
private _setTileStyler(rowHeight: string): void {
if (this._tileStyler) {
this._tileStyler.reset(this);
}

if (rowHeight === MD_FIT_MODE) {
this._tileStyler = new FitTileStyler();
} else if (this._rowHeight && this._rowHeight.indexOf(':') > -1) {
this._tileStyler = new RatioTileStyler(this._rowHeight);
} else if (rowHeight && rowHeight.indexOf(':') > -1) {
this._tileStyler = new RatioTileStyler(rowHeight);
} else {
this._tileStyler = new FixedTileStyler(this._rowHeight);
this._tileStyler = new FixedTileStyler(rowHeight);
}
}

/** Computes and applies the size and position for all children grid tiles. */
private _layoutTiles(): void {
let tracker = new TileCoordinator(this.cols, this._tiles);
let direction = this._dir ? this._dir.value : 'ltr';
const tracker = new TileCoordinator(this.cols, this._tiles);
const direction = this._dir ? this._dir.value : 'ltr';
this._tileStyler.init(this.gutterSize, tracker, this.cols, direction);

this._tiles.forEach((tile, index) => {
let pos = tracker.positions[index];
const pos = tracker.positions[index];
this._tileStyler.setStyle(tile, pos.row, pos.col);
});

this._setListStyle(this._tileStyler.getComputedHeight());
}

/** Sets style on the main grid-list element, given the style name and value. */
_setListStyle(style: [string, string] | null): void {
_setListStyle(style: [string, string | null] | null): void {
if (style) {
this._renderer.setStyle(this._element.nativeElement, style[0], style[1]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/grid-list/grid-tile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class MdGridTile {
* Sets the style of the grid-tile element. Needs to be set manually to avoid
* "Changed after checked" errors that would occur with HostBinding.
*/
_setStyle(property: string, value: string): void {
_setStyle(property: string, value: any): void {
this._renderer.setStyle(this._element.nativeElement, property, value);
}
}
Expand Down
34 changes: 33 additions & 1 deletion src/lib/grid-list/tile-styler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {MdGridList} from './grid-list';
import {MdGridTile} from './grid-tile';
import {TileCoordinator} from './tile-coordinator';

Expand Down Expand Up @@ -139,6 +140,13 @@ export abstract class TileStyler {
* @docs-private
*/
getComputedHeight(): [string, string] | null { return null; }

/**
* Called when the tile styler is swapped out with a different one. To be used for cleanup.
* @param list Grid list that the styler was attached to.
* @docs-private
*/
abstract reset(list: MdGridList);
}


Expand Down Expand Up @@ -166,6 +174,15 @@ export class FixedTileStyler extends TileStyler {
'height', calc(`${this.getTileSpan(this.fixedRowHeight)} + ${this.getGutterSpan()}`)
];
}

reset(list: MdGridList) {
list._setListStyle(['height', null]);

list._tiles.forEach(tile => {
tile._setStyle('top', null);
tile._setStyle('height', null);
});
}
}


Expand Down Expand Up @@ -203,8 +220,17 @@ export class RatioTileStyler extends TileStyler {
];
}

reset(list: MdGridList) {
list._setListStyle(['padding-bottom', null]);

list._tiles.forEach(tile => {
tile._setStyle('margin-top', null);
tile._setStyle('padding-top', null);
});
}

private _parseRatio(value: string): void {
let ratioParts = value.split(':');
const ratioParts = value.split(':');

if (ratioParts.length !== 2) {
throw Error(`md-grid-list: invalid ratio given for row-height: "${value}"`);
Expand Down Expand Up @@ -237,6 +263,12 @@ export class FitTileStyler extends TileStyler {
tile._setStyle('height', calc(this.getTileSize(baseTileHeight, tile.rowspan)));
}

reset(list: MdGridList) {
list._tiles.forEach(tile => {
tile._setStyle('top', null);
tile._setStyle('height', null);
});
}
}


Expand Down

0 comments on commit 4250594

Please sign in to comment.