Skip to content

Commit 7db2762

Browse files
andrewseguintinayuangao
authored andcommitted
feat(data-table): minimal beginning implementation (#4468)
* feat(cdk-table): initial version * add files * remove unnecessary deps * add test * add tests * edit comments * minor style changes * changes due to comments * add test for column classes * add OnPush to rest of components * remove double quotes from colors.ts * lint fies * add comments to demo css * comments * split directives into separate files * lint * add content check in tests * renaming directives * remove fdescribe * rename private placeholders; adjust comments; change CollectionViewer * lint * change jasmine array param * remove unnecessary import from spec * move out of core; add console warning about instability * move jasmine-matchers * fix demo
1 parent 5c48949 commit 7db2762

File tree

21 files changed

+2087
-20
lines changed

21 files changed

+2087
-20
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<div class="demo-table-container mat-elevation-z4">
2+
3+
<cdk-table #table [dataSource]="dataSource">
4+
5+
<!-- Column Definition: ID -->
6+
<ng-container cdkColumnDef="userId">
7+
<cdk-header-cell *cdkHeaderCellDef> ID </cdk-header-cell>
8+
<cdk-cell *cdkCellDef="let row"> {{row.id}} </cdk-cell>
9+
</ng-container>
10+
11+
<!-- Column Definition: Progress -->
12+
<ng-container cdkColumnDef="progress">
13+
<cdk-header-cell *cdkHeaderCellDef> Progress </cdk-header-cell>
14+
<cdk-cell *cdkCellDef="let row">
15+
<div class="demo-progress-stat">{{row.progress}}%</div>
16+
<div class="demo-progress-indicator-container">
17+
<div class="demo-progress-indicator"
18+
[style.background]="row.progress > 50 ? 'green' : 'red'"
19+
[style.opacity]="getOpacity(row.progress)"
20+
[style.width.%]="row.progress"></div>
21+
</div>
22+
</cdk-cell>
23+
</ng-container>
24+
25+
<!-- Column Definition: Name -->
26+
<ng-container cdkColumnDef="userName">
27+
<cdk-header-cell *cdkHeaderCellDef> Name </cdk-header-cell>
28+
<cdk-cell *cdkCellDef="let row"> {{row.name}} </cdk-cell>
29+
</ng-container>
30+
31+
<!-- Column Definition: Color -->
32+
<ng-container cdkColumnDef="color">
33+
<cdk-header-cell *cdkHeaderCellDef>Color</cdk-header-cell>
34+
<cdk-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </cdk-cell>
35+
</ng-container>
36+
37+
<cdk-header-row *cdkHeaderRowDef="propertiesToDisplay"></cdk-header-row>
38+
<cdk-row *cdkRowDef="let row; columns: propertiesToDisplay"></cdk-row>
39+
</cdk-table>
40+
</div>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* Structure */
2+
.demo-table-container {
3+
display: flex;
4+
flex-direction: column;
5+
max-height: 800px;
6+
7+
// Table fills in the remaining area with a scroll
8+
.cdk-table {
9+
flex: 1 1 auto;
10+
overflow: auto;
11+
}
12+
}
13+
14+
/*
15+
* Styles to make the demo's cdk-table match the material design spec
16+
* https://material.io/guidelines/components/data-tables.html
17+
*/
18+
.cdk-table {
19+
display: block;
20+
background: white;
21+
}
22+
23+
.cdk-row, .cdk-header-row {
24+
display: flex;
25+
border-bottom: 1px solid #ccc;
26+
align-items: center;
27+
height: 48px;
28+
padding: 0 8px;
29+
}
30+
31+
.cdk-cell, .cdk-header-cell {
32+
width: 150px;
33+
padding: 10px;
34+
position: relative;
35+
flex: 1;
36+
}
37+
38+
.cdk-header-cell {
39+
font-size: 12px;
40+
font-weight: bold;
41+
color: rgba(0, 0, 0, 0.54);
42+
}
43+
44+
.cdk-cell {
45+
font-size: 13px;
46+
color: rgba(0, 0, 0, 0.87);
47+
}
48+
49+
/* Column and cell styles */
50+
.cdk-column-userId {
51+
max-width: 32px;
52+
}
53+
54+
.cdk-column-userName {
55+
max-width: 80px;
56+
}
57+
58+
.cdk-column-progress {
59+
&.cdk-cell {
60+
display: flex;
61+
position: relative;
62+
63+
.demo-progress-stat {
64+
width: 32px;
65+
padding-right: 8px;
66+
}
67+
68+
.demo-progress-indicator-container {
69+
position: relative;
70+
flex-grow: 1;
71+
display: flex;
72+
align-items: center;
73+
}
74+
.demo-progress-indicator {
75+
border-radius: 8px;
76+
height: 8px;
77+
}
78+
}
79+
}
80+
81+
.cdk-column-color {
82+
max-width: 160px;
83+
84+
&.cdk-cell {
85+
font-weight: bold;
86+
font-size: 16px;
87+
font-family: cursive;
88+
}
89+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Component} from '@angular/core';
2+
import {PeopleDatabase} from './people-database';
3+
import {PersonDataSource} from './person-data-source';
4+
5+
@Component({
6+
moduleId: module.id,
7+
selector: 'data-table-demo',
8+
templateUrl: 'data-table-demo.html',
9+
styleUrls: ['data-table-demo.css'],
10+
})
11+
export class DataTableDemo {
12+
dataSource: PersonDataSource;
13+
propertiesToDisplay = ['userId', 'userName', 'progress', 'color'];
14+
15+
constructor(private _peopleDatabase: PeopleDatabase) { }
16+
17+
ngOnInit() {
18+
this.dataSource = new PersonDataSource(this._peopleDatabase);
19+
}
20+
21+
getOpacity(progress: number) {
22+
let distanceFromMiddle = Math.abs(50 - progress);
23+
return distanceFromMiddle / 50 + .3;
24+
}
25+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {Injectable} from '@angular/core';
2+
import {NAMES} from '../dataset/names';
3+
import {COLORS} from '../dataset/colors';
4+
5+
export let LATEST_ID: number = 0;
6+
7+
export interface UserData {
8+
id: string;
9+
name: string;
10+
progress: string;
11+
color: string;
12+
}
13+
14+
@Injectable()
15+
export class PeopleDatabase {
16+
data: UserData[] = [];
17+
18+
constructor() {
19+
for (let i = 0; i < 100; i++) { this.addPerson(); }
20+
}
21+
22+
addPerson() {
23+
const name =
24+
NAMES[Math.round(Math.random() * (NAMES.length - 1))] + ' ' +
25+
NAMES[Math.round(Math.random() * (NAMES.length - 1))].charAt(0) + '.';
26+
27+
this.data.push({
28+
id: (++LATEST_ID).toString(),
29+
name: name,
30+
progress: Math.round(Math.random() * 100).toString(),
31+
color: COLORS[Math.round(Math.random() * (COLORS.length - 1))]
32+
});
33+
}
34+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import {CollectionViewer, DataSource} from '@angular/material';
2+
import {Observable} from 'rxjs/Observable';
3+
import {PeopleDatabase, UserData} from './people-database';
4+
5+
export class PersonDataSource extends DataSource<any> {
6+
_renderedData: any[] = [];
7+
8+
constructor(private _peopleDatabase: PeopleDatabase) {
9+
super();
10+
}
11+
12+
connect(collectionViewer: CollectionViewer): Observable<UserData[]> {
13+
return collectionViewer.viewChanged.map((view: {start: number, end: number}) => {
14+
// Set the rendered rows length to the virtual page size. Fill in the data provided
15+
// from the index start until the end index or pagination size, whichever is smaller.
16+
this._renderedData.length = this._peopleDatabase.data.length;
17+
18+
const buffer = 20;
19+
let rangeStart = Math.max(0, view.start - buffer);
20+
let rangeEnd = Math.min(this._peopleDatabase.data.length, view.end + buffer);
21+
22+
for (let i = rangeStart; i < rangeEnd; i++) {
23+
this._renderedData[i] = this._peopleDatabase.data[i];
24+
}
25+
26+
return this._renderedData;
27+
});
28+
}
29+
}

src/demo-app/dataset/colors.ts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
export const COLORS = [
2+
'AliceBlue',
3+
'AntiqueWhite',
4+
'Aqua',
5+
'Aquamarine',
6+
'Azure',
7+
'Beige',
8+
'Bisque',
9+
'Black',
10+
'BlanchedAlmond',
11+
'Blue',
12+
'BlueViolet',
13+
'Brown',
14+
'BurlyWood',
15+
'CadetBlue',
16+
'Chartreuse',
17+
'Chocolate',
18+
'Coral',
19+
'CornflowerBlue',
20+
'Cornsilk',
21+
'Crimson',
22+
'Cyan',
23+
'DarkBlue',
24+
'DarkCyan',
25+
'DarkGoldenRod',
26+
'DarkGray',
27+
'DarkGrey',
28+
'DarkGreen',
29+
'DarkKhaki',
30+
'DarkMagenta',
31+
'DarkOliveGreen',
32+
'Darkorange',
33+
'DarkOrchid',
34+
'DarkRed',
35+
'DarkSalmon',
36+
'DarkSeaGreen',
37+
'DarkSlateBlue',
38+
'DarkSlateGray',
39+
'DarkSlateGrey',
40+
'DarkTurquoise',
41+
'DarkViolet',
42+
'DeepPink',
43+
'DeepSkyBlue',
44+
'DimGray',
45+
'DimGrey',
46+
'DodgerBlue',
47+
'FireBrick',
48+
'FloralWhite',
49+
'ForestGreen',
50+
'Fuchsia',
51+
'Gainsboro',
52+
'GhostWhite',
53+
'Gold',
54+
'GoldenRod',
55+
'Gray',
56+
'Grey',
57+
'Green',
58+
'GreenYellow',
59+
'HoneyDew',
60+
'HotPink',
61+
'IndianRed',
62+
'Indigo',
63+
'Ivory',
64+
'Khaki',
65+
'Lavender',
66+
'LavenderBlush',
67+
'LawnGreen',
68+
'LemonChiffon',
69+
'LightBlue',
70+
'LightCoral',
71+
'LightCyan',
72+
'LightGoldenRodYellow',
73+
'LightGray',
74+
'LightGrey',
75+
'LightGreen',
76+
'LightPink',
77+
'LightSalmon',
78+
'LightSeaGreen',
79+
'LightSkyBlue',
80+
'LightSlateGray',
81+
'LightSlateGrey',
82+
'LightSteelBlue',
83+
'LightYellow',
84+
'Lime',
85+
'LimeGreen',
86+
'Linen',
87+
'Magenta',
88+
'Maroon',
89+
'MediumAquaMarine',
90+
'MediumBlue',
91+
'MediumOrchid',
92+
'MediumPurple',
93+
'MediumSeaGreen',
94+
'MediumSlateBlue',
95+
'MediumSpringGreen',
96+
'MediumTurquoise',
97+
'MediumVioletRed',
98+
'MidnightBlue',
99+
'MintCream',
100+
'MistyRose',
101+
'Moccasin',
102+
'NavajoWhite',
103+
'Navy',
104+
'OldLace',
105+
'Olive',
106+
'OliveDrab',
107+
'Orange',
108+
'OrangeRed',
109+
'Orchid',
110+
'PaleGoldenRod',
111+
'PaleGreen',
112+
'PaleTurquoise',
113+
'PaleVioletRed',
114+
'PapayaWhip',
115+
'PeachPuff',
116+
'Peru',
117+
'Pink',
118+
'Plum',
119+
'PowderBlue',
120+
'Purple',
121+
'Red',
122+
'RosyBrown',
123+
'RoyalBlue',
124+
'SaddleBrown',
125+
'Salmon',
126+
'SandyBrown',
127+
'SeaGreen',
128+
'SeaShell',
129+
'Sienna',
130+
'Silver',
131+
'SkyBlue',
132+
'SlateBlue',
133+
'SlateGray',
134+
'SlateGrey',
135+
'Snow',
136+
'SpringGreen',
137+
'SteelBlue',
138+
'Tan',
139+
'Teal',
140+
'Thistle',
141+
'Tomato',
142+
'Turquoise',
143+
'Violet',
144+
'Wheat',
145+
'White',
146+
'WhiteSmoke',
147+
'Yellow',
148+
'YellowGreen'
149+
];

0 commit comments

Comments
 (0)