Row Expansion Customization

Expand rows to display custom content below each row. This demo renders a sub-component that shows the full row data as formatted JSON when a row is expanded.

Username Account Status Role Avg Session Duration Company Name Last Visited At Visit Count
Orion_Senger77
suspended moderator 117 Nitzsche, Reichert and Barton 29 Oct 2025 08:57:18 PDT 3
Katelyn.Boyle
pending admin 118 Marks - Lynch 28 Aug 2024 12:41:35 PDT 3
Vincenza.Feest30
pending admin 77 Bergstrom - Rohan 11 Aug 2025 00:33:27 PDT 3
Amie_Davis29
suspended moderator 115 Christiansen - Sporer 07 Mar 2025 05:43:50 PDT 2
Antonette.Hessel15
active user 118 Ortiz, Conroy and Schimmel 11 Oct 2025 23:47:13 PDT 97
Emilia_Hilll
pending user 38 Keebler - Wisoky 03 Sep 2025 17:26:08 PDT 24
Kelly_Flatley11
suspended admin 23 Heaney LLC 24 Dec 2024 17:32:54 PDT 2
Monique_Mraz
suspended admin 118 Abshire Inc 17 Sep 2025 08:15:30 PDT 2
Valentina_Swift83
pending moderator 119 Flatley Inc 04 Jan 2025 21:43:16 PDT 271
Citlalli_Greenholt
suspended admin 70 Goldner LLC 10 Jul 2024 00:43:55 PDT 116
import {JsonPipe} from "@angular/common"
import {Component} from "@angular/core"

import {ButtonModule} from "@qualcomm-ui/angular/button"
import {ProgressRingModule} from "@qualcomm-ui/angular/progress-ring"
import {createAngularTable, TableModule} from "@qualcomm-ui/angular/table"
import {getCoreRowModel, getExpandedRowModel} from "@qualcomm-ui/core/table"

import {createUserQuery, type User, userColumns} from "./data"

@Component({
  imports: [TableModule, ButtonModule, ProgressRingModule, JsonPipe],
  selector: "row-expansion-customization-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
                    [attr.colspan]="header.colSpan"
                    [style.minWidth.px]="header.column.columnDef.minSize"
                  >
                    @if (!header.isPlaceholder) {
                      <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>
              @if (row.getIsExpanded()) {
                <tr q-table-row>
                  <td
                    q-table-cell
                    [attr.colspan]="row.getVisibleCells().length"
                  >
                    <pre
                      class="w-fit rounded bg-transparent p-2 font-mono text-xs"
                      >{{ row.original | json }}</pre
                    >
                  </td>
                </tr>
              }
            }
          </tbody>
        </table>
      </div>
    </div>
  `,
})
export class RowExpansionCustomizationDemo {
  protected readonly query = createUserQuery(10)

  protected table = createAngularTable<User>(() => ({
    columns: userColumns,
    data: this.query.data() || [],
    getCoreRowModel: getCoreRowModel(),
    getExpandedRowModel: getExpandedRowModel(),
    getRowCanExpand: () => true,
  }))
}
Last updated on by Ryan Bower