Skip to content

Commit 6790b2c

Browse files
committed
docs(table): initial table docs
1 parent b00f838 commit 6790b2c

22 files changed

+1026
-14
lines changed

src/cdk/table/table.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
The CDK Data Table displays rows of data with fully customizable cell templates.
2+
Its single responsibility is the efficient rendering of rows in a fully accessible way.
3+
4+
The CDK table provides a foundation upon which other features, such as sorting and pagination, can be built.
5+
Because the CDK table enforces no opinions on these matters, developers have full control over the interaction patterns associated with the table.
6+
7+
For a Material Design styled table, see `<md-table>`, which builds on top of the CDK Data Table.
8+
9+
In the near future, the material library will include an additional "simple table",
10+
building `<md-table>` with a more minimal interface and sorting, pagination, and selection built-in.
11+
12+
<!-- example(table-basic) -->
13+
14+
## Using the CDK Data Table
15+
16+
### Writing your table template
17+
18+
The first step to writing the CDK Data Table template is to define the columns that will be used in your table.
19+
Each column definition will consist of a header cell template and a data cell template by using
20+
the `<cdk-header-cell>` and `<cdk-cell>`, respectively. These will be wrapped in an `<ng-container>` and given a column name.
21+
22+
Both the `<cdk-header-cell>` and `<cdk-cell>` require an additional directive so that the table can
23+
capture the inner template. For `<cdk-header-cell>` you must include the attribute `*cdkHeaderCellDef`
24+
and for `<cdk-cell>` you must include `*cdkCellDef`. Note that the `*cdkCellDef` provides an outlet
25+
to capture the cell’s row data to be used in the template.
26+
27+
```html
28+
<ng-container cdkColumnDef="column_a">
29+
<cdk-header-cell *cdkHeaderCellDef> Column A </cdk-header-cell>
30+
<cdk-cell *cdkCellDef="let row"> {{row.a}} </cdk-cell>
31+
</ng-container>
32+
```
33+
34+
After the columns have been defined, you must include a `<cdk-header-row>` and `<cdk-row>` which will
35+
each take an array of the column names. This will be the columns that will be rendered in the table and in the order provided.
36+
37+
```html
38+
<cdk-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></cdk-header-row>
39+
<cdk-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></cdk-row>
40+
```
41+
42+
In the following template, we have a data table that displays three columns: Column A, Column B, and Column C.
43+
The <cdk-header-row> and <cdk-row> are given an input of what columns to display.
44+
45+
```html
46+
<cdk-table [dataSource]="dataSource">
47+
<!-- Column A Definition -->
48+
<ng-container cdkColumnDef="column_a">
49+
<cdk-header-cell *cdkHeaderCellDef> Column A </cdk-header-cell>
50+
<cdk-cell *cdkCellDef="let row"> {{row.a}} </cdk-cell>
51+
</ng-container>
52+
53+
<!-- Column B Definition -->
54+
<ng-container cdkColumnDef="column_b">
55+
<cdk-header-cell *cdkHeaderCellDef> Column B </cdk-header-cell>
56+
<cdk-cell *cdkCellDef="let row"> {{row.b}} </cdk-cell>
57+
</ng-container>
58+
59+
<!-- Column C Definition -->
60+
<ng-container cdkColumnDef="column_c">
61+
<cdk-header-cell *cdkHeaderCellDef> Column C </cdk-header-cell>
62+
<cdk-cell *cdkCellDef="let row"> {{row.c}} </cdk-cell>
63+
</ng-container>
64+
65+
<!-- Header and Row Declarations (define columns; provide attribute and event binding) -->
66+
<cdk-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></cdk-header-row>
67+
<cdk-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></cdk-row>
68+
</cdk-table>
69+
```
70+
71+
It is not required to display all the columns that are defined within the template,
72+
nor is the order required. For example, if we wanted the table to display only Column B
73+
and Column A and in that order, then the template would look like this:
74+
75+
```html
76+
<cdk-header-row *cdkHeaderRowDef="['column_b', 'column_a’]"></cdk-header-row>
77+
<cdk-row *cdkRowDef="let row; columns: ['column_b', 'column_a']"></cdk-row>
78+
```
79+
80+
Adding attribute and event binding to the header and rows is as simple as applying them to the
81+
<cdk-header-row> and <cdk-row>. For example, here the table is adding a click handler to both.
82+
In addition, the CSS class `a-bigger-than-twenty` will be applied to any row where its data’s `a` property is greater than 20.
83+
84+
```html
85+
<cdk-header-row *cdkHeaderRowDef="['column_b', 'column_a']"
86+
(click)=”handleHeaderRowClick(row)”>
87+
</cdk-header-row>
88+
89+
<cdk-row *cdkRowDef="let row; columns: ['column_b', 'column_a']"
90+
[class.a-bigger-than-twenty]=”row.a > 20”
91+
(click)=”handleRowClick(row)”>
92+
</cdk-row>
93+
```
94+
95+
Changing the list of columns provided to the `<cdk-header-row>` and `<cdk-row>` will automatically
96+
cause the table to re-render to reflect those changes. For more information, see Dynamic Columns below under Features.
97+
98+
### Connecting the table to a data source
99+
Data is provided to the table through the `DataSource` interface. When the table receives a DataSource,
100+
it calls its connect function to receive an observable that emits an array of data. Whenever the Data Source emits data to this stream, the table will use it to render its rows.
101+
102+
Since the Data Source provides this data stream, it is responsible for watching for data changes
103+
and notifying the table when to re-render. Examples of these data changes includes sorting, pagination, filtering, and more.
104+
To see how these examples can be incorporated in the Data Source, see below under Features.
105+
106+
Note that a trackBy function can be provided to the table similar to Angular’s ngFor trackBy.
107+
This allows you to customize how the table to identifies rows and improves performance.
108+
109+
In the future, the connect function will be able to use the CollectionViewer parameter to be
110+
notified about table events, such as what rows the user is currently viewing. This could be used to
111+
help the Data Source know what data does not need to be retrieved and rendered, further improving performance.
112+
113+
## Material Table
114+
To use the CDK Data Table with styles matching the Material Design spec, you can use the `<md-table>`
115+
defined in `@angular/material`. This will build on the CDK Data Table and apply built-in Material Design styles.
116+
117+
The interface for the `<md-table>` matches the `<cdk-table>`, except that its element selectors
118+
will be prefixed with `md-` instead of `cdk-`.
119+
120+
Note that the column definition directives (`cdkColumnDef` and `cdkHeaderCellDef`) are still prefixed with `cdk-`.
121+
122+
```html
123+
<md-table [dataSource]="dataSource">
124+
<!-- Column A Definition -->
125+
<ng-container cdkColumnDef="column_a">
126+
<md-header-cell *cdkHeaderCellDef> Column A </md-header-cell>
127+
<md-cell *cdkCellDef="let row"> {{row.a}} </md-cell>
128+
</ng-container>
129+
130+
<!-- Column B Definition -->
131+
<ng-container cdkColumnDef="column_b">
132+
<md-header-cell *cdkHeaderCellDef> Column B </md-header-cell>
133+
<md-cell *cdkCellDef="let row"> {{row.b}} </md-cell>
134+
</ng-container>
135+
136+
<!-- Column C Definition -->
137+
<ng-container cdkColumnDef="column_c">
138+
<md-header-cell *cdkHeaderCellDef> Column C </md-header-cell>
139+
<md-cell *cdkCellDef="let row"> {{row.c}} </md-cell>
140+
</ng-container>
141+
142+
<!-- Header and Row Declarations (define columns; provide attribute and event binding) -->
143+
<md-header-row *cdkHeaderRowDef="['column_a', 'column_b', 'column_c']"></md-header-row>
144+
<md-row *cdkRowDef="let row; columns: ['column_a', 'column_b', 'column_c']"></md-row>
145+
</md-table>
146+
```
147+
148+
## Simple Table
149+
150+
In the near future, we would like to provide a simple version of the data table that includes an easy-to-use interface,
151+
material styling, data array input, and out-of-the-box features such as sorting, pagination, and selection.
152+
153+
## Features
154+
155+
The CDK Table’s responsibility is to handle efficient rendering of rows and it’s the Data Source’s job
156+
to let the table know what data should be rendered. As such, features that manipulate what data should
157+
be rendered should be the responsibility of the data source.
158+
159+
### Pagination
160+
Use the MdPagination component to add data paging to the data table. The data source can listen to
161+
paging events from the component and appropriately slice the right data from whatever data provider
162+
is used. Sending this new data to the table will cause it to render the new page of data.
163+
164+
<!-- example(table-pagination) -->
165+
166+
### Sorting
167+
Use the MdSort component to enable sorting the table's data through the column headers.
168+
The data source can listen to sorting events from the component and sort the data before giving it
169+
to the table to render.
170+
171+
<!-- example(table-sorting) -->
172+
173+
### Filtering
174+
175+
<!--- example(table-filtering) -->

src/demo-app/table/table-demo.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ <h3>CdkTable Example</h3>
7676
<cdk-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </cdk-cell>
7777
</ng-container>
7878

79-
<cdk-header-row *cdkHeaderRowDef="propertiesToDisplay"></cdk-header-row>
80-
<cdk-row *cdkRowDef="let row; columns: propertiesToDisplay;
79+
<cdk-header-row *cdkHeaderRowDef="displayedColumns"></cdk-header-row>
80+
<cdk-row *cdkRowDef="let row; columns: displayedColumns;
8181
let first = first; let last = last; let even = even; let odd = odd"
8282
[ngClass]="{
8383
'demo-row-highlight-first': highlights.has('first') && first,
@@ -92,7 +92,7 @@ <h3>MdTable Example</h3>
9292

9393
<div class="demo-table-container demo-mat-table-example mat-elevation-z4">
9494

95-
<table-header-demo (shiftColumns)="propertiesToDisplay.push(propertiesToDisplay.shift())"
95+
<table-header-demo (shiftColumns)="displayedColumns.push(displayedColumns.shift())"
9696
(toggleColorColumn)="toggleColorColumn()">
9797
</table-header-demo>
9898

@@ -130,8 +130,8 @@ <h3>MdTable Example</h3>
130130
<md-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </md-cell>
131131
</ng-container>
132132

133-
<md-header-row *cdkHeaderRowDef="propertiesToDisplay"></md-header-row>
134-
<md-row *cdkRowDef="let row; columns: propertiesToDisplay"></md-row>
133+
<md-header-row *cdkHeaderRowDef="displayedColumns"></md-header-row>
134+
<md-row *cdkRowDef="let row; columns: displayedColumns"></md-row>
135135

136136
</md-table>
137137

src/demo-app/table/table-demo.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export type TrackByStrategy = 'id' | 'reference' | 'index';
1616
})
1717
export class TableDemo {
1818
dataSource: PersonDataSource | null;
19-
propertiesToDisplay: UserProperties[] = [];
19+
displayedColumns: UserProperties[] = [];
2020
trackByStrategy: TrackByStrategy = 'reference';
2121
changeReferences = false;
2222
highlights = new Set<string>();
@@ -32,15 +32,15 @@ export class TableDemo {
3232
}
3333

3434
connect() {
35-
this.propertiesToDisplay = ['userId', 'userName', 'progress', 'color'];
35+
this.displayedColumns = ['userId', 'userName', 'progress', 'color'];
3636
this.dataSource = new PersonDataSource(this._peopleDatabase,
3737
this._paginator, this.sort);
3838
this._peopleDatabase.initialize();
3939
}
4040

4141
disconnect() {
4242
this.dataSource = null;
43-
this.propertiesToDisplay = [];
43+
this.displayedColumns = [];
4444
}
4545

4646
getOpacity(progress: number) {
@@ -57,11 +57,11 @@ export class TableDemo {
5757
}
5858

5959
toggleColorColumn() {
60-
let colorColumnIndex = this.propertiesToDisplay.indexOf('color');
60+
let colorColumnIndex = this.displayedColumns.indexOf('color');
6161
if (colorColumnIndex == -1) {
62-
this.propertiesToDisplay.push('color');
62+
this.displayedColumns.push('color');
6363
} else {
64-
this.propertiesToDisplay.splice(colorColumnIndex, 1);
64+
this.displayedColumns.splice(colorColumnIndex, 1);
6565
}
6666
}
6767

src/material-examples/example-module.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ import {
8585
MdRadioModule, MdSelectModule, MdSidenavModule, MdSliderModule, MdSlideToggleModule,
8686
MdSnackBarModule, MdTabsModule, MdToolbarModule, MdTooltipModule
8787
} from '@angular/material';
88+
import {CdkTableModule} from '@angular/cdk';
89+
import {TableOverviewExample} from './table-overview/table-overview-example';
90+
import {TablePaginationExample} from './table-pagination/table-pagination-example';
91+
import {TableBasicExample} from './table-basic/table-basic-example';
92+
import {TableSortingExample} from './table-sorting/table-sorting-example';
93+
import {TableFilteringExample} from './table-filtering/table-filtering-example';
8894

8995
export interface LiveExample {
9096
title: string;
@@ -182,6 +188,11 @@ export const EXAMPLE_COMPONENTS = {
182188
component: SnackBarComponentExample
183189
},
184190
'snack-bar-overview': {title: 'Basic snack-bar', component: SnackBarOverviewExample},
191+
'table-overview': {title: 'Feature-rich data table', component: TableOverviewExample},
192+
'table-pagination': {title: 'Table with pagination', component: TablePaginationExample},
193+
'table-sorting': {title: 'Table with sorting', component: TableSortingExample},
194+
'table-filtering': {title: 'Table with filtering', component: TableFilteringExample},
195+
'table-basic': {title: 'Basic table', component: TableBasicExample},
185196
'tabs-overview': {title: 'Basic tabs', component: TabsOverviewExample},
186197
'tabs-template-label': {title: 'Coming soon!', component: TabsTemplateLabelExample},
187198
'toolbar-multirow': {title: 'Multi-row toolbar', component: ToolbarMultirowExample},
@@ -195,6 +206,7 @@ export const EXAMPLE_COMPONENTS = {
195206
*/
196207
@NgModule({
197208
exports: [
209+
CdkTableModule,
198210
MdAutocompleteModule,
199211
MdButtonModule,
200212
MdButtonToggleModule,
@@ -280,6 +292,11 @@ export const EXAMPLE_LIST = [
280292
SnackBarComponentExample,
281293
PizzaPartyComponent,
282294
SnackBarOverviewExample,
295+
TableBasicExample,
296+
TableOverviewExample,
297+
TableFilteringExample,
298+
TablePaginationExample,
299+
TableSortingExample,
283300
TabsOverviewExample,
284301
TabsTemplateLabelExample,
285302
ToolbarMultirowExample,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/* Structure */
2+
.example-container {
3+
display: flex;
4+
flex-direction: column;
5+
max-height: 500px;
6+
background: white;
7+
min-width: 300px;
8+
}
9+
10+
.example-header {
11+
min-height: 64px;
12+
display: flex;
13+
align-items: center;
14+
padding-left: 24px;
15+
font-size: 20px;
16+
}
17+
18+
/*
19+
* Styles to make the demo's cdk-table match the material design spec
20+
* https://material.io/guidelines/components/data-tables.html
21+
*/
22+
.cdk-table {
23+
flex: 1 1 auto;
24+
overflow: auto;
25+
}
26+
27+
.cdk-row, .cdk-header-row {
28+
display: flex;
29+
border-bottom: 1px solid #ccc;
30+
align-items: center;
31+
height: 48px;
32+
padding: 0 24px;
33+
}
34+
35+
.cdk-cell, .cdk-header-cell {
36+
flex: 1;
37+
}
38+
39+
.cdk-header-cell {
40+
font-size: 12px;
41+
font-weight: bold;
42+
color: rgba(0, 0, 0, 0.54);
43+
}
44+
45+
.cdk-cell {
46+
font-size: 13px;
47+
color: rgba(0, 0, 0, 0.87);
48+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<div class="example-container mat-elevation-z8">
2+
<div class="example-header"> Users </div>
3+
4+
<cdk-table #table [dataSource]="dataSource">
5+
6+
<!--- Note that these columns can be defined in any order.
7+
The actual rendered columns are set as a property on the row definition" -->
8+
9+
<!-- ID Column -->
10+
<ng-container cdkColumnDef="userId">
11+
<cdk-header-cell *cdkHeaderCellDef> ID </cdk-header-cell>
12+
<cdk-cell *cdkCellDef="let row"> {{row.id}} </cdk-cell>
13+
</ng-container>
14+
15+
<!-- Progress Column -->
16+
<ng-container cdkColumnDef="progress">
17+
<cdk-header-cell *cdkHeaderCellDef> Progress </cdk-header-cell>
18+
<cdk-cell *cdkCellDef="let row"> {{row.progress}}% </cdk-cell>
19+
</ng-container>
20+
21+
<!-- Name Column -->
22+
<ng-container cdkColumnDef="userName">
23+
<cdk-header-cell *cdkHeaderCellDef> Name </cdk-header-cell>
24+
<cdk-cell *cdkCellDef="let row"> {{row.name}} </cdk-cell>
25+
</ng-container>
26+
27+
<!-- Color Column -->
28+
<ng-container cdkColumnDef="color">
29+
<cdk-header-cell *cdkHeaderCellDef>Color</cdk-header-cell>
30+
<cdk-cell *cdkCellDef="let row" [style.color]="row.color"> {{row.color}} </cdk-cell>
31+
</ng-container>
32+
33+
<cdk-header-row *cdkHeaderRowDef="displayedColumns"></cdk-header-row>
34+
<cdk-row *cdkRowDef="let row; columns: displayedColumns;">
35+
</cdk-row>
36+
</cdk-table>
37+
</div>

0 commit comments

Comments
 (0)