Skip to main content
The CdkTable provides behavior for data tables without styling.

Installation

npm install @angular/cdk
import {CdkTableModule} from '@angular/cdk/table';

Basic Usage

import {Component} from '@angular/core';

export interface User {
  id: number;
  name: string;
  email: string;
}

@Component({
  selector: 'app-table-example',
  template: `
    <table cdk-table [dataSource]="users">
      <!-- ID Column -->
      <ng-container cdkColumnDef="id">
        <th cdk-header-cell *cdkHeaderCellDef>ID</th>
        <td cdk-cell *cdkCellDef="let user">{{ user.id }}</td>
      </ng-container>

      <!-- Name Column -->
      <ng-container cdkColumnDef="name">
        <th cdk-header-cell *cdkHeaderCellDef>Name</th>
        <td cdk-cell *cdkCellDef="let user">{{ user.name }}</td>
      </ng-container>

      <!-- Email Column -->
      <ng-container cdkColumnDef="email">
        <th cdk-header-cell *cdkHeaderCellDef>Email</th>
        <td cdk-cell *cdkCellDef="let user">{{ user.email }}</td>
      </ng-container>

      <!-- Header Row -->
      <tr cdk-header-row *cdkHeaderRowDef="displayedColumns"></tr>
      
      <!-- Data Rows -->
      <tr cdk-row *cdkRowDef="let row; columns: displayedColumns"></tr>
    </table>
  `,
})
export class TableExample {
  users: User[] = [
    {id: 1, name: 'John', email: '[email protected]'},
    {id: 2, name: 'Jane', email: '[email protected]'},
  ];
  
  displayedColumns = ['id', 'name', 'email'];
}

With DataSource

import {DataSource} from '@angular/cdk/collections';
import {Observable, of} from 'rxjs';

export class UserDataSource extends DataSource<User> {
  constructor(private users: User[]) {
    super();
  }

  connect(): Observable<User[]> {
    return of(this.users);
  }

  disconnect() {}
}

@Component({
  template: `<table cdk-table [dataSource]="dataSource">...</table>`,
})
export class DataSourceExample {
  dataSource = new UserDataSource([
    {id: 1, name: 'John', email: '[email protected]'},
  ]);
}

Sticky Headers

<table cdk-table [dataSource]="users">
  <ng-container cdkColumnDef="name">
    <th cdk-header-cell *cdkHeaderCellDef [sticky]="true">Name</th>
    <td cdk-cell *cdkCellDef="let user">{{ user.name }}</td>
  </ng-container>
  
  <tr cdk-header-row *cdkHeaderRowDef="columns; sticky: true"></tr>
  <tr cdk-row *cdkRowDef="let row; columns: columns"></tr>
</table>

API Reference

cdk-table

InputTypeDescription
dataSourceDataSource | ArrayData to display
trackByTrackByFunctionTrack items by identity

cdkColumnDef

Defines a column.

cdk-header-cell

Header cell template.

cdk-cell

Data cell template.

cdk-header-row / cdk-row

Row templates.

See Also

Build docs developers (and LLMs) love