or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

buttons-indicators.mddata-display.mddate-time.mdform-controls.mdindex.mdlayout.mdnavigation.mdpopups-modals.mdtesting.mdtheming.md
tile.json

data-display.mddocs/

Data Display

Components for displaying and manipulating structured data including tables, trees, pagination, and sorting with comprehensive data source integration.

Capabilities

Table

Flexible data table component with sorting, pagination, and filtering support.

/**
 * Data table component for displaying structured data
 */
class MatTable<T> extends CdkTable<T> {
  // Extends CDK table with Material Design styling
}

/**
 * Data source with built-in filtering, sorting, and pagination
 */
class MatTableDataSource<T> extends DataSource<T> {
  @Input() data: T[];
  @Input() filter: string;
  @Input() filterPredicate: (data: T, filter: string) => boolean;
  @Input() filteredData: T[];
  @Input() paginator: MatPaginator | null;
  @Input() sort: MatSort | null;
  @Input() sortData: (data: T[], sort: MatSort) => T[];
  @Input() sortingDataAccessor: (data: T, sortHeaderId: string) => string | number;
  
  connect(collectionViewer: CollectionViewer): Observable<T[]>;
  disconnect(collectionViewer: CollectionViewer): void;
  
  _updateChangeSubscription(): void;
  _filterData(data: T[]): T[];
  _orderData(data: T[]): T[];
  _pageData(data: T[]): T[];
  _updatePaginator(filteredDataLength: number): void;
}

/**
 * Text column component for simple data display
 */
class MatTextColumn<T> {
  @Input() name: string;
  @Input() headerText: string;
  @Input() dataAccessor: (data: T, name: string) => string;
  @Input() justify: 'start' | 'end' | 'center';
  
  readonly columnDef: MatColumnDef;
  readonly cell: MatCellDef;
  readonly headerCell: MatHeaderCellDef;
}

/**
 * Table module
 */
class MatTableModule {
  // NgModule for table functionality
}

Pagination

Pagination controls for navigating through large datasets.

/**
 * Paginator component for controlling data pagination
 */
class MatPaginator implements OnInit, OnDestroy, CanDisable, HasInitialized {
  @Input() color: ThemePalette;
  @Input() pageIndex: number;
  @Input() length: number;
  @Input() pageSize: number;
  @Input() pageSizeOptions: number[];
  @Input() hidePageSize: boolean;
  @Input() showFirstLastButtons: boolean;
  @Input() selectConfig: MatPaginatorSelectConfig;
  @Input() disabled: boolean;
  
  @Output() readonly page: EventEmitter<PageEvent>;
  
  readonly _intl: MatPaginatorIntl;
  readonly _changeDetectorRef: ChangeDetectorRef;
  
  nextPage(): void;
  previousPage(): void;
  firstPage(): void;
  lastPage(): void;
  hasNextPage(): boolean;
  hasPreviousPage(): boolean;
  getNumberOfPages(): number;
  _changePageSize(pageSize: number): void;
  _nextButtonsDisabled(): boolean;
  _previousButtonsDisabled(): boolean;
  _getRangeLabel(page: number, pageSize: number, length: number): string;
}

/**
 * Paginator internationalization service
 */
class MatPaginatorIntl {
  readonly changes: Subject<void>;
  
  itemsPerPageLabel: string;
  nextPageLabel: string;
  previousPageLabel: string;
  firstPageLabel: string;
  lastPageLabel: string;
  
  getRangeLabel: (page: number, pageSize: number, length: number) => string;
}

/**
 * Page change event
 */
interface PageEvent {
  pageIndex: number;
  previousPageIndex?: number;
  pageSize: number;
  length: number;
}

/**
 * Paginator select configuration
 */
interface MatPaginatorSelectConfig {
  disableOptionCentering?: boolean;
  panelClass?: string | string[];
}

/**
 * Paginator module
 */
class MatPaginatorModule {
  // NgModule for paginator functionality
}

Sort

Sortable table headers with multi-column sorting support.

/**
 * Sortable container directive
 */
class MatSort implements OnChanges, OnDestroy, OnInit, CanDisable {
  @Input('matSortActive') active: string;
  @Input('matSortStart') start: SortDirection;
  @Input('matSortDirection') direction: SortDirection;
  @Input('matSortDisableClear') disableClear: boolean;
  @Input('matSortDisabled') disabled: boolean;
  
  @Output('matSortChange') readonly sortChange: EventEmitter<Sort>;
  
  readonly sortables: Map<string, MatSortable>;
  
  register(sortable: MatSortable): void;
  deregister(sortable: MatSortable): void;
  sort(sortable: MatSortable): void;
  getNextSortDirection(sortable: MatSortable): SortDirection;
}

/**
 * Sortable column header component
 */
class MatSortHeader implements CanDisable, MatSortable, OnDestroy, OnInit, AfterViewInit {
  @Input('mat-sort-header') id: string;
  @Input() ariaLabel: string;
  @Input() start: SortDirection;
  @Input() disabled: boolean;
  @Input() sortActionDescription: string;
  @Input() disableClear: boolean;
  
  readonly _sort: MatSort;
  readonly _columnDef: MatColumnDef;
  readonly _showIndicatorHint: boolean;
  readonly _disableViewStateAnimation: boolean;
  
  _updateArrowDirection(): void;
  _setAnimationTransitionState(viewState: ArrowViewStateTransition): void;
  _toggleOnInteraction(): void;
  _setIndicatorHintVisible(visible: boolean): void;
  _setAnimationTransitionState(viewState: ArrowViewStateTransition): void;
  _isSorted(): boolean;
  _getArrowDirectionState(): string;
  _getArrowViewState(): string;
  _renderArrow(): boolean;
  _getSortActionDescription(): string;
  _updateSortActionDescription(): void;
}

/**
 * Sort header internationalization service
 */
class MatSortHeaderIntl {
  readonly changes: Subject<void>;
  sortButtonLabel: (id: string) => string;
}

/**
 * Sort direction type
 */
type SortDirection = 'asc' | 'desc' | '';

/**
 * Sort state interface
 */
interface Sort {
  active: string;
  direction: SortDirection;
}

/**
 * Sortable interface
 */
interface MatSortable {
  id: string;
  start: SortDirection;
  disableClear: boolean;
}

/**
 * Arrow view state transition type
 */
type ArrowViewStateTransition = 'fromTo' | 'toFrom' | 'enter' | 'leave';

/**
 * Sort module
 */
class MatSortModule {
  // NgModule for sort functionality
}

Tree

Hierarchical data display component with nested and flat data structure support.

/**
 * Tree component for displaying hierarchical data
 */
class MatTree<T, K = T> extends CdkTree<T, K> {
  // Material Design tree extending CDK tree
}

/**
 * Tree node directive
 */
class MatTreeNode<T, K = T> extends CdkTreeNode<T, K> {
  @Input() role: 'treeitem' | 'group';
  @Input() disabled: boolean;
  @Input() tabIndex: number;
  
  // Material Design tree node
}

/**
 * Tree node padding directive
 */
class MatTreeNodePadding<T, K = T> extends CdkTreeNodePadding<T, K> {
  @Input('matTreeNodePadding') level: number;
  @Input('matTreeNodePaddingIndent') indent: number | string;
  
  // Adds appropriate padding for tree node level
}

/**
 * Tree node toggle directive
 */
class MatTreeNodeToggle<T, K = T> extends CdkTreeNodeToggle<T, K> {
  @Input('matTreeNodeToggleRecursive') recursive: boolean;
  
  // Toggle expansion/collapse of tree node
}

/**
 * Tree node outlet directive
 */
class MatTreeNodeOutlet extends CdkTreeNodeOutlet {
  // Outlet where tree nodes are rendered
}

/**
 * Flat tree data source
 */
class MatTreeFlatDataSource<T, F, K = F> extends DataSource<F> {
  constructor(
    private _treeControl: FlatTreeControl<F, K>,
    private _treeFlattener: MatTreeFlattener<T, F, K>,
    initialData?: T[]
  );
  
  @Input() data: T[];
  
  connect(collectionViewer: CollectionViewer): Observable<F[]>;
  disconnect(): void;
}

/**
 * Nested tree data source
 */
class MatTreeNestedDataSource<T> extends DataSource<T> {
  constructor(private _treeControl: NestedTreeControl<T>);
  
  @Input() data: T[];
  
  connect(collectionViewer: CollectionViewer): Observable<T[]>;
  disconnect(): void;
}

/**
 * Tree flattener for converting nested to flat structure
 */
class MatTreeFlattener<T, F, K = F> {
  constructor(
    public transformFunction: (node: T, level: number) => F,
    public getLevel: (node: F) => number,
    public isExpandable: (node: F) => boolean,
    public getChildren: (node: T) => Observable<T[]> | T[] | undefined | null
  );
  
  _flattenNode(node: T, level: number, resultNodes: F[], parentMap: boolean[]): F[];
  _flattenChildren(children: T[], level: number, resultNodes: F[], parentMap: boolean[]): void;
  flattenNodes(structuredData: T[]): F[];
  expandFlattenedNodes(nodes: F[], treeControl: TreeControl<F, K>): F[];
}

/**
 * Tree module
 */
class MatTreeModule {
  // NgModule for tree functionality  
}

Usage Examples:

import { MatTableModule } from '@angular/material/table';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSortModule } from '@angular/material/sort';
import { MatTreeModule } from '@angular/material/tree';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';

interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  // ... more data
];

interface FoodNode {
  name: string;
  children?: FoodNode[];
}

const TREE_DATA: FoodNode[] = [
  {
    name: 'Fruit',
    children: [
      {name: 'Apple'},
      {name: 'Banana'},
      {name: 'Orange'}
    ]
  },
  {
    name: 'Vegetables',
    children: [
      {name: 'Carrot'},
      {name: 'Lettuce'},
      {name: 'Broccoli'}
    ]
  }
];

@Component({
  imports: [
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
    MatTreeModule,
    MatInputModule,
    MatFormFieldModule,
    MatIconModule,
    MatButtonModule
  ],
  template: `
    <!-- Data Table with Sorting and Pagination -->
    <mat-form-field>
      <mat-label>Filter</mat-label>
      <input matInput (keyup)="applyFilter($event)" placeholder="Ex. Mia">
    </mat-form-field>

    <mat-table [dataSource]="dataSource" matSort>
      <ng-container matColumnDef="position">
        <mat-header-cell *matHeaderCellDef mat-sort-header> No. </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.position}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="name">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="weight">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Weight </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.weight}} </mat-cell>
      </ng-container>

      <ng-container matColumnDef="symbol">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Symbol </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.symbol}} </mat-cell>
      </ng-container>

      <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
      <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>

    <mat-paginator [pageSizeOptions]="[5, 10, 20]" 
                   showFirstLastButtons 
                   aria-label="Select page of periodic elements">
    </mat-paginator>

    <!-- Tree Display -->
    <mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl">
      <mat-tree-node *matTreeNodeDef="let node" matTreeNodePadding>
        <button mat-icon-button disabled></button>
        {{node.name}}
      </mat-tree-node>
      
      <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding>
        <button mat-icon-button matTreeNodeToggle
                [attr.aria-label]="'Toggle ' + node.name">
          <mat-icon class="mat-icon-rtl-mirror">
            {{treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right'}}
          </mat-icon>
        </button>
        {{node.name}}
      </mat-tree-node>
    </mat-tree>
  `
})
export class DataDisplayExample implements OnInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);
  
  treeControl = new NestedTreeControl<FoodNode>(node => node.children);
  treeDataSource = new MatTreeNestedDataSource<FoodNode>();

  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ViewChild(MatSort) sort: MatSort;

  ngOnInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
    this.treeDataSource.data = TREE_DATA;
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  hasChild = (_: number, node: FoodNode) => !!node.children && node.children.length > 0;
}