parent
2cb066215a
commit
8ef183b593
|
@ -1,5 +1,9 @@
|
||||||
|
<style>
|
||||||
|
md-grid-tile {
|
||||||
|
background: lightblue;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<div class="md-grid-list">
|
<div class="md-grid-list">
|
||||||
<div class="md-grid-tile">
|
<content></content>
|
||||||
<figure></figure>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,17 +2,24 @@ import {Component, onDestroy, onChange, onAllChangesDone} from 'angular2/src/cor
|
||||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||||
import {Parent} from 'angular2/src/core/annotations_impl/visibility';
|
import {Parent} from 'angular2/src/core/annotations_impl/visibility';
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isString, NumberWrapper, stringify} from 'angular2/src/facade/lang';
|
import {StringWrapper, isPresent, isString, NumberWrapper, RegExpWrapper} from 'angular2/src/facade/lang';
|
||||||
|
import {Math} from 'angular2/src/facade/math';
|
||||||
|
|
||||||
// TODO(jelbourn): Set appropriate aria attributes for grid list elements.
|
// TODO(jelbourn): Set appropriate aria attributes for grid list elements.
|
||||||
|
// TODO(jelbourn): Animations.
|
||||||
|
// TODO(jelbourn): Conditional (responsive) column count / row size.
|
||||||
|
// TODO(jelbourn): Re-layout on window resize / media change (debounced).
|
||||||
|
// TODO(jelbourn): gridTileHeader and gridTileFooter.
|
||||||
|
// TODO(jelbourn): rowHeightMode enum (after TS conversion).
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'md-grid-list',
|
selector: 'md-grid-list',
|
||||||
properties: {
|
properties: {
|
||||||
'cols': 'cols',
|
'cols': 'cols',
|
||||||
|
'rowHeight': 'row-height',
|
||||||
'gutterSize': 'gutter-size'
|
'gutterSize': 'gutter-size'
|
||||||
},
|
},
|
||||||
lifecycle: [onChange]
|
lifecycle: [onAllChangesDone]
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
templateUrl: 'angular2_material/src/components/grid_list/grid_list.html'
|
templateUrl: 'angular2_material/src/components/grid_list/grid_list.html'
|
||||||
|
@ -21,14 +28,17 @@ export class MdGridList {
|
||||||
/** List of tiles that are being rendered. */
|
/** List of tiles that are being rendered. */
|
||||||
tiles: List<MdGridTile>;
|
tiles: List<MdGridTile>;
|
||||||
|
|
||||||
/** Number of columns being rendered. Can be either string or number */
|
/** Number of columns being rendered. */
|
||||||
cols;
|
_cols: number;
|
||||||
|
|
||||||
|
/** Number of rows being rendered (computed). */
|
||||||
|
rows: number;
|
||||||
|
|
||||||
/** Mode used to determine row heights. See RowHeightMode. */
|
/** Mode used to determine row heights. See RowHeightMode. */
|
||||||
rowHeightMode: string;
|
rowHeightMode: string;
|
||||||
|
|
||||||
/** Fixed row height, as given by the user. Only used for 'fixed' mode. */
|
/** Fixed row height, as given by the user. Only used for 'fixed' mode. */
|
||||||
fixedRowHeight: number;
|
fixedRowHeight: string;
|
||||||
|
|
||||||
/** Ratio width:height given by user to determine row height. Only used for 'ratio' mode.*/
|
/** Ratio width:height given by user to determine row height. Only used for 'ratio' mode.*/
|
||||||
rowHeightRatio: number;
|
rowHeightRatio: number;
|
||||||
|
@ -36,23 +46,58 @@ export class MdGridList {
|
||||||
/** The amount of space between tiles. This will be something like '5px' or '2em'. */
|
/** The amount of space between tiles. This will be something like '5px' or '2em'. */
|
||||||
gutterSize: string;
|
gutterSize: string;
|
||||||
|
|
||||||
/** List used to track the amount of space available. */
|
|
||||||
spaceTracker: List<number>;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.tiles = [];
|
this.tiles = [];
|
||||||
|
this.rows = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set cols(value) {
|
||||||
|
this._cols = isString(value) ? NumberWrapper.parseInt(value, 10) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get cols() {
|
||||||
|
return this._cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set internal representation of row height from the user-provided value. */
|
||||||
|
set rowHeight(value) {
|
||||||
|
if (value === 'fit') {
|
||||||
|
this.rowHeightMode = 'fit';
|
||||||
|
} else if (StringWrapper.contains(value, ':')) {
|
||||||
|
var ratioParts = StringWrapper.split(value, RegExpWrapper.create(':'));
|
||||||
|
if (ratioParts.length !== 2) {
|
||||||
|
throw `md-grid-list: invalid ratio given for row-height: "${value}"`;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.rowHeightMode = 'ratio';
|
||||||
|
this.rowHeightRatio =
|
||||||
|
NumberWrapper.parseFloat(ratioParts[0]) / NumberWrapper.parseFloat(ratioParts[1]);
|
||||||
|
} else {
|
||||||
|
this.rowHeightMode = 'fixed';
|
||||||
|
this.fixedRowHeight = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onAllChangesDone() {
|
onAllChangesDone() {
|
||||||
|
this.layoutTiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange(_) {
|
/** Computes and applies the size and position for all children grid tiles. */
|
||||||
if (!isPresent(this.spaceTracker)) {
|
layoutTiles() {
|
||||||
if (isString(this.cols)) {
|
var tracker = new TileCoordinator(this.cols, this.tiles);
|
||||||
this.cols = NumberWrapper.parseIntAutoRadix(this.cols);
|
this.rows = tracker.rowCount;
|
||||||
}
|
|
||||||
this.spaceTracker = ListWrapper.createFixedSize(this.cols);
|
for (var i = 0; i < this.tiles.length; i++) {
|
||||||
ListWrapper.fill(this.spaceTracker, 0);
|
var pos = tracker.positions[i];
|
||||||
|
var tile = this.tiles[i];
|
||||||
|
var style = this.getTileStyle(tile, pos.row, pos.col);
|
||||||
|
|
||||||
|
tile.styleWidth = style.width;
|
||||||
|
tile.styleHeight = style.height;
|
||||||
|
tile.styleTop = style.top;
|
||||||
|
tile.styleLeft = style.left;
|
||||||
|
tile.styleMarginTop = style.marginTop;
|
||||||
|
tile.stylePaddingTop = style.paddingTop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,15 +117,6 @@ export class MdGridList {
|
||||||
ListWrapper.remove(this.tiles, tile);
|
ListWrapper.remove(this.tiles, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Change handler invoked when bindings are resolved or when bindings have changed.
|
|
||||||
* Performs a layout.
|
|
||||||
*/
|
|
||||||
performLayout() {
|
|
||||||
//console.log('laying out!');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the amount of space a single 1x1 tile would take up (width or height).
|
* Computes the amount of space a single 1x1 tile would take up (width or height).
|
||||||
* Used as a basis for other calculations.
|
* Used as a basis for other calculations.
|
||||||
|
@ -94,7 +130,7 @@ export class MdGridList {
|
||||||
// edges, each tile only uses a fration (gutterShare = numGutters / numCells) of the gutter
|
// edges, each tile only uses a fration (gutterShare = numGutters / numCells) of the gutter
|
||||||
// size. (Imagine having one gutter per tile, and then breaking up the extra gutter on the
|
// size. (Imagine having one gutter per tile, and then breaking up the extra gutter on the
|
||||||
// edge evenly among the cells).
|
// edge evenly among the cells).
|
||||||
return `${sizePercent}% - ( ${this.gutterSize} * ${gutterFraction} )`;
|
return `(${sizePercent}% - ( ${this.gutterSize} * ${gutterFraction} ))`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,43 +158,57 @@ export class MdGridList {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Gets the style properties to be applied to a tile for the given row and column index. */
|
||||||
getTileStyle(tile: MdGridTile, rowIndex: number, colIndex: number): TileStyle {
|
getTileStyle(tile: MdGridTile, rowIndex: number, colIndex: number): TileStyle {
|
||||||
// Percent of the available horizontal space that one column takes up.
|
// Percent of the available horizontal space that one column takes up.
|
||||||
var percentWidthPerTile = this.cols / 100;
|
var percentWidthPerTile = 100 / this.cols;
|
||||||
|
|
||||||
// Fraction of the gutter size that each column takes up.
|
// Fraction of the vertical gutter size that each column takes up.
|
||||||
// For example, if there are 5 columns, each column uses 4/5 = 0.8 times the gutter width.
|
// For example, if there are 5 columns, each column uses 4/5 = 0.8 times the gutter width.
|
||||||
var gutterWidthFractionPerTile = (this.cols - 1) / this.cols;
|
var gutterWidthFractionPerTile = (this.cols - 1) / this.cols;
|
||||||
|
|
||||||
// Base horizontal size of a column.
|
// Base horizontal size of a column.
|
||||||
var baseTileWidth = getBaseTileSize(percentWidthPerTile, gutterWidthFractionPerTile);
|
var baseTileWidth = this.getBaseTileSize(percentWidthPerTile, gutterWidthFractionPerTile);
|
||||||
|
|
||||||
// The width and horizontal position of each tile is always calculated the same way, but the
|
// The width and horizontal position of each tile is always calculated the same way, but the
|
||||||
// height and vertical position depends on the rowMode.
|
// height and vertical position depends on the rowMode.
|
||||||
var tileStyle = new TileStyle();
|
var tileStyle = new TileStyle();
|
||||||
tileStyle.left = getTilePosition(baseTileWidth, colIndex);
|
tileStyle.left = this.getTilePosition(baseTileWidth, colIndex);
|
||||||
tileStyle.width = getTileSize(baseTileWidth, tile.colspan);
|
tileStyle.width = this.getTileSize(baseTileWidth, tile.colspan);
|
||||||
|
|
||||||
// TODO: make cases enums when we support enums
|
// TODO: make cases enums when we support enums
|
||||||
switch (this.rowHeightMode) {
|
switch (this.rowHeightMode) {
|
||||||
case 'fixed':
|
case 'fixed':
|
||||||
// In fixed mode, simply use the given row height.
|
// In fixed mode, simply use the given row height.
|
||||||
tileStyle.top = getTilePosition(stringify(this.fixedRowHeight), rowIndex);
|
tileStyle.top = this.getTilePosition(this.fixedRowHeight, rowIndex);
|
||||||
tileStyle.height = getTileSize(stringify(this.fixedRowHeight), tile.rowspan);
|
tileStyle.height = this.getTileSize(this.fixedRowHeight, tile.rowspan);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'ratio':
|
case 'ratio':
|
||||||
var percentHeightPerTile = percentWidthPerTile / this.rowHeightRatio;
|
var percentHeightPerTile = percentWidthPerTile / this.rowHeightRatio;
|
||||||
let baseTileHeight = getBaseTileSize(percentHeightPerTile, gutterWidthFractionPerTile);
|
var baseTileHeight = this.getBaseTileSize(percentHeightPerTile, gutterWidthFractionPerTile);
|
||||||
|
|
||||||
// Use paddingTop and marginTop to maintain the given aspect ratio, as
|
// Use paddingTop and marginTop to maintain the given aspect ratio, as
|
||||||
// a percentage-based value for these properties is applied to the *width* of the
|
// a percentage-based value for these properties is applied versus the *width* of the
|
||||||
// containing block. See http://www.w3.org/TR/CSS2/box.html#margin-properties
|
// containing block. See http://www.w3.org/TR/CSS2/box.html#margin-properties
|
||||||
tileStyle.marginTop = getTilePosition(baseTileHeight, rowIndex);
|
tileStyle.marginTop = this.getTilePosition(baseTileHeight, rowIndex);
|
||||||
tileStyle.paddingTop = getTileSize(baseTileHeight, tile.rowspan);
|
tileStyle.paddingTop = this.getTileSize(baseTileHeight, tile.rowspan);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'fit':
|
case 'fit':
|
||||||
|
// Percent of the available vertical space that one row takes up.
|
||||||
|
var percentHeightPerTile = 100 / this.cols;
|
||||||
|
|
||||||
|
// Fraction of the horizontal gutter size that each column takes up.
|
||||||
|
var gutterHeightFractionPerTile = (this.rows - 1) / this.rows;
|
||||||
|
|
||||||
|
// Base vertical size of a column.
|
||||||
|
var baseTileHeight =
|
||||||
|
this.getBaseTileSize(percentHeightPerTile, gutterHeightFractionPerTile);
|
||||||
|
|
||||||
|
tileStyle.top = this.getTilePosition(baseTileHeight, rowIndex);
|
||||||
|
tileStyle.height = this.getTileSize(baseTileHeight, tile.rowspan);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,20 +234,20 @@ export class MdGridList {
|
||||||
lifecycle: [onDestroy, onChange]
|
lifecycle: [onDestroy, onChange]
|
||||||
})
|
})
|
||||||
@View({
|
@View({
|
||||||
template: `<figure><content></content></figure>`
|
templateUrl: 'angular2_material/src/components/grid_list/grid_tile.html'
|
||||||
})
|
})
|
||||||
export class MdGridTile {
|
export class MdGridTile {
|
||||||
gridList: MdGridList;
|
gridList: MdGridList;
|
||||||
rowspan: number;
|
_rowspan: number;
|
||||||
colspan: number;
|
_colspan: number;
|
||||||
|
|
||||||
styleHeight:any;
|
styleHeight: string;
|
||||||
styleWidth:any;
|
styleWidth: string;
|
||||||
styleTop:any;
|
styleTop: string;
|
||||||
styleLeft:any;
|
styleLeft: string;
|
||||||
styleMarginTop:any;
|
styleMarginTop: string;
|
||||||
stylePaddingTop:any;
|
stylePaddingTop: string;
|
||||||
role:any;
|
role: string;
|
||||||
|
|
||||||
isRegisteredWithGridList: boolean;
|
isRegisteredWithGridList: boolean;
|
||||||
|
|
||||||
|
@ -209,9 +259,22 @@ export class MdGridTile {
|
||||||
// Tiles default to 1x1, but rowspan and colspan can be changed via binding.
|
// Tiles default to 1x1, but rowspan and colspan can be changed via binding.
|
||||||
this.rowspan = 1;
|
this.rowspan = 1;
|
||||||
this.colspan = 1;
|
this.colspan = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// DEBUG
|
set rowspan(value) {
|
||||||
this.styleHeight = `${gridList.tiles.length * 100}px`;
|
this._rowspan = isString(value) ? NumberWrapper.parseInt(value, 10) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get rowspan() {
|
||||||
|
return this._rowspan;
|
||||||
|
}
|
||||||
|
|
||||||
|
set colspan(value) {
|
||||||
|
this._colspan = isString(value) ? NumberWrapper.parseInt(value, 10) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get colspan() {
|
||||||
|
return this._colspan;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,8 +286,6 @@ export class MdGridTile {
|
||||||
if (!this.isRegisteredWithGridList) {
|
if (!this.isRegisteredWithGridList) {
|
||||||
this.gridList.addTile(this);
|
this.gridList.addTile(this);
|
||||||
this.isRegisteredWithGridList = true;
|
this.isRegisteredWithGridList = true;
|
||||||
} else {
|
|
||||||
this.gridList.performLayout();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,6 +297,141 @@ export class MdGridTile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for determining, from a list of tiles, the (row, col) position of each of those tiles
|
||||||
|
* in the grid. This is necessary (rather than just rendering the tiles in normal document flow)
|
||||||
|
* because the tiles can have a rowspan.
|
||||||
|
*
|
||||||
|
* The positioning algorithm greedily places each tile as soon as it encounters a gap in the grid
|
||||||
|
* large enough to accomodate it so that the tiles still render in the same order in which they
|
||||||
|
* are given.
|
||||||
|
*
|
||||||
|
* The basis of the algorithm is the use of an array to track the already placed tiles. Each
|
||||||
|
* element of the array corresponds to a column, and the value indicates how many cells in that
|
||||||
|
* column are already occupied; zero indicates an empty cell. Moving "down" to the next row
|
||||||
|
* decrements each value in the tracking array (indicating that the column is one cell closer to
|
||||||
|
* being free).
|
||||||
|
*/
|
||||||
|
class TileCoordinator {
|
||||||
|
// Tracking array (see class description).
|
||||||
|
tracker: List<int>;
|
||||||
|
|
||||||
|
// Index at which the search for the next gap will start.
|
||||||
|
columnIndex: int;
|
||||||
|
|
||||||
|
// The current row index.
|
||||||
|
rowIndex: int;
|
||||||
|
|
||||||
|
// The computed (row, col) position of each tile (the output).
|
||||||
|
positions: List<Position>;
|
||||||
|
|
||||||
|
constructor(numColumns: number, tiles: List<MdGridTile>) {
|
||||||
|
this.columnIndex = 0;
|
||||||
|
this.rowIndex = 0;
|
||||||
|
|
||||||
|
this.tracker = ListWrapper.createFixedSize(numColumns);
|
||||||
|
ListWrapper.fill(this.tracker, 0);
|
||||||
|
|
||||||
|
this.positions = ListWrapper.map(tiles, tile => this._trackTile(tile));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the number of rows occupied by tiles. */
|
||||||
|
get rowCount() {
|
||||||
|
return this.rowIndex + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_trackTile(tile: MdGridTile): Position {
|
||||||
|
if (tile.colspan > this.tracker.length) {
|
||||||
|
throw `Tile with colspan ${tile.colspan} is wider
|
||||||
|
than grid with cols="${this.tracker.length}".`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start index is inclusive, end index is exclusive.
|
||||||
|
var gapStartIndex = -1;
|
||||||
|
var gapEndIndex = -1;
|
||||||
|
|
||||||
|
// Look for a gap large enough to fit the given tile. Empty spaces are marked with a zero.
|
||||||
|
do {
|
||||||
|
// If we've reached the end of the row, go to the next row
|
||||||
|
if (this.columnIndex + tile.colspan > this.tracker.length) {
|
||||||
|
this._nextRow();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gapStartIndex = ListWrapper.indexOf(this.tracker, 0, this.columnIndex);
|
||||||
|
|
||||||
|
// If there are no more empty spaces in this row at all, move on to the next row.
|
||||||
|
if (gapStartIndex == -1) {
|
||||||
|
this._nextRow();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gapEndIndex = this._findGapEndIndex(gapStartIndex);
|
||||||
|
|
||||||
|
// If a gap large enough isn't found, we want to start looking immediately after the current
|
||||||
|
// gap on the next iteration.
|
||||||
|
this.columnIndex = gapStartIndex + 1;
|
||||||
|
|
||||||
|
// Continue iterating until we find a gap wide enough for this tile.
|
||||||
|
} while (gapEndIndex - gapStartIndex < tile.colspan);
|
||||||
|
|
||||||
|
// We now have a space big enough for this tile, so place it.
|
||||||
|
this._markTilePosition(gapStartIndex, tile);
|
||||||
|
|
||||||
|
// The next time we look for a gap, the search will start at columnIndex, which should be
|
||||||
|
// immediately after the tile that has just been placed.
|
||||||
|
this.columnIndex = gapStartIndex + tile.colspan;
|
||||||
|
|
||||||
|
return new Position(this.rowIndex, gapStartIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Move "down" to the next row. */
|
||||||
|
_nextRow() {
|
||||||
|
this.columnIndex = 0;
|
||||||
|
this.rowIndex++;
|
||||||
|
|
||||||
|
// Decrement all spaces by one to reflect moving down one row.
|
||||||
|
for (var i = 0; i < this.tracker.length; i++) {
|
||||||
|
this.tracker[i] = Math.max(0, this.tracker[i] - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the end index (exclusive) of a gap given the index from which to start looking.
|
||||||
|
* The gap ends when a non-zero value is found.
|
||||||
|
*/
|
||||||
|
_findGapEndIndex(gapStartIndex: number): number {
|
||||||
|
for (var i = gapStartIndex + 1; i < this.tracker.length; i++) {
|
||||||
|
if (this.tracker[i] != 0) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The gap ends with the end of the row.
|
||||||
|
return this.tracker.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update the tile tracker to account for the given tile in the given space. */
|
||||||
|
_markTilePosition(start, tile) {
|
||||||
|
for (var i = 0; i < tile.colspan; i++) {
|
||||||
|
this.tracker[start + i] = tile.rowspan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Simple data structure for tile position (row, col). */
|
||||||
|
class Position {
|
||||||
|
row: number;
|
||||||
|
col: number;
|
||||||
|
|
||||||
|
constructor(row: number, col: number) {
|
||||||
|
this.row = row;
|
||||||
|
this.col = col;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Simple data structure for style values to be applied to a tile. */
|
/** Simple data structure for style values to be applied to a tile. */
|
||||||
class TileStyle {
|
class TileStyle {
|
||||||
height: string;
|
height: string;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<style>@import "angular2_material/src/components/grid_list/grid-list.css";</style>
|
||||||
|
|
||||||
|
<figure>
|
||||||
|
<content></content>
|
||||||
|
</figure>
|
|
@ -1,28 +1,40 @@
|
||||||
<style>@import "angular2_material/src/components/grid_list/grid-list.css";</style>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
md-grid-tile {
|
md-grid-tile {
|
||||||
background-color: lightblue;
|
background-color: lightblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
md-grid-list {
|
||||||
|
min-height: 400px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<h2>grid-list demo</h2>
|
<h2>grid-list demo</h2>
|
||||||
|
|
||||||
<md-grid-list cols="5" gutter-size="2em">
|
<md-grid-list cols="4" row-height="50px" gutter-size="2em">
|
||||||
|
|
||||||
<md-grid-tile cols="5">
|
<md-grid-tile rowspan="1" colspan="2"> Tile #1 </md-grid-tile>
|
||||||
Tile #1
|
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
|
||||||
</md-grid-tile>
|
<md-grid-tile rowspan="3" colspan="1"> Tile #3 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="2" colspan="2"> Tile #4 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="3"> Tile #5 </md-grid-tile>
|
||||||
|
|
||||||
<md-grid-tile rowspan="2" colspan="2">
|
</md-grid-list>
|
||||||
Tile #2
|
|
||||||
</md-grid-tile>
|
|
||||||
|
|
||||||
<md-grid-tile [rowspan]="tile3RowSpan" [colspan]="tile3RowSpan">
|
<hr>
|
||||||
Tile #3
|
|
||||||
</md-grid-tile>
|
|
||||||
|
|
||||||
|
<md-grid-list cols="4" row-height="50px" gutter-size="2em">
|
||||||
|
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #1 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #2 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #3 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #4 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #5 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #6 </md-grid-tile>
|
||||||
|
<md-grid-tile rowspan="1" colspan="1"> Tile #7 </md-grid-tile>
|
||||||
|
|
||||||
</md-grid-list>
|
</md-grid-list>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue