Row Expansion (Sub rows)
Row expansion enables tables to display hierarchical data by allowing rows to expand and reveal nested sub-rows. This is useful for representing parent-child relationships, grouped data, or tree structures within a table.
The demo below shows a table with expandable rows containing nested data. Each row with children displays an expand button that toggles visibility of its sub-rows. The header includes an expand-all button that expands or collapses all rows at once. Visual indentation indicates the depth level of each row in the hierarchy.
Username | Account Status | Role | Avg Session Duration | Company Name | Last Visited At | Visit Count |
|---|
import {Component} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {PaginationModule} from "@qualcomm-ui/angular/pagination"
import {ProgressRingModule} from "@qualcomm-ui/angular/progress-ring"
import {
createAngularTable,
createTablePagination,
TableModule,
} from "@qualcomm-ui/angular/table"
import {
getCoreRowModel,
getExpandedRowModel,
getPaginationRowModel,
} from "@qualcomm-ui/core/table"
import {createUserQuery, type User, userColumns} from "./data"
@Component({
imports: [TableModule, PaginationModule, ButtonModule, ProgressRingModule],
selector: "row-expansion-demo",
template: `
<div q-table-root>
<div q-table-action-bar>
<button
q-button
size="sm"
variant="outline"
[disabled]="query.isFetching()"
(click)="query.refetch()"
>
Refresh Data
</button>
@if (query.isFetching()) {
<div q-progress-ring size="xs"></div>
}
</div>
<div q-table-scroll-container>
<table q-table-table>
<thead q-table-header>
@for (
headerGroup of table.getHeaderGroups();
track headerGroup.id
) {
<tr q-table-row>
@for (header of headerGroup.headers; track header.id) {
<th q-table-header-cell>
<ng-container *renderHeader="header; let value">
{{ value }}
</ng-container>
</th>
}
</tr>
}
</thead>
<tbody q-table-body>
@for (row of table.getRowModel().rows; track row.id) {
<tr q-table-row>
@for (cell of row.getVisibleCells(); track cell.id) {
<td q-table-cell>
<ng-container *renderCell="cell; let value">
{{ value }}
</ng-container>
</td>
}
</tr>
}
</tbody>
</table>
</div>
<div
q-table-pagination
[count]="pagination.count()"
[page]="pagination.page()"
[pageSize]="pagination.pageSize()"
(pageChanged)="pagination.onPageChange($event)"
>
<div *paginationContext="let context" q-pagination-page-metadata>
@let meta = context.pageMetadata;
{{ meta.pageStart }}-{{ meta.pageEnd }} of {{ meta.count }} results
</div>
<div q-pagination-page-buttons></div>
</div>
</div>
`,
})
export class RowExpansionDemo {
protected readonly query = createUserQuery(100, 5, 3)
protected table = createAngularTable<User>(() => ({
columns: userColumns,
data: this.query.data() || [],
getCoreRowModel: getCoreRowModel(),
getExpandedRowModel: getExpandedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getSubRows: (row: User) => row.subRows,
}))
protected pagination = createTablePagination(this.table)
}Last updated on by Ryan Bower