@tailng-ui/primitives 0.41.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +2 -2
  2. package/src/lib/layout/index.d.ts +1 -0
  3. package/src/lib/layout/index.d.ts.map +1 -1
  4. package/src/lib/layout/index.js +1 -0
  5. package/src/lib/layout/index.js.map +1 -1
  6. package/src/lib/layout/table/__tests__/tng-table.test-harness.d.ts +300 -0
  7. package/src/lib/layout/table/__tests__/tng-table.test-harness.d.ts.map +1 -0
  8. package/src/lib/layout/table/__tests__/tng-table.test-harness.js +2492 -0
  9. package/src/lib/layout/table/__tests__/tng-table.test-harness.js.map +1 -0
  10. package/src/lib/layout/table/index.d.ts +6 -0
  11. package/src/lib/layout/table/index.d.ts.map +1 -0
  12. package/src/lib/layout/table/index.js +6 -0
  13. package/src/lib/layout/table/index.js.map +1 -0
  14. package/src/lib/layout/table/tng-table-render.d.ts +175 -0
  15. package/src/lib/layout/table/tng-table-render.d.ts.map +1 -0
  16. package/src/lib/layout/table/tng-table-render.js +304 -0
  17. package/src/lib/layout/table/tng-table-render.js.map +1 -0
  18. package/src/lib/layout/table/tng-table-sizing.d.ts +75 -0
  19. package/src/lib/layout/table/tng-table-sizing.d.ts.map +1 -0
  20. package/src/lib/layout/table/tng-table-sizing.js +361 -0
  21. package/src/lib/layout/table/tng-table-sizing.js.map +1 -0
  22. package/src/lib/layout/table/tng-table-sort.d.ts +53 -0
  23. package/src/lib/layout/table/tng-table-sort.d.ts.map +1 -0
  24. package/src/lib/layout/table/tng-table-sort.js +167 -0
  25. package/src/lib/layout/table/tng-table-sort.js.map +1 -0
  26. package/src/lib/layout/table/tng-table-virtual.d.ts +55 -0
  27. package/src/lib/layout/table/tng-table-virtual.d.ts.map +1 -0
  28. package/src/lib/layout/table/tng-table-virtual.js +250 -0
  29. package/src/lib/layout/table/tng-table-virtual.js.map +1 -0
  30. package/src/lib/layout/table/tng-table.d.ts +362 -0
  31. package/src/lib/layout/table/tng-table.d.ts.map +1 -0
  32. package/src/lib/layout/table/tng-table.js +1490 -0
  33. package/src/lib/layout/table/tng-table.js.map +1 -0
@@ -0,0 +1,2492 @@
1
+ import { Component, ViewChild, computed, signal } from '@angular/core';
2
+ import { RouterLink } from '@angular/router';
3
+ import { createTngFilterController, createTngPaginationController, createTngSortController, } from '@tailng-ui/cdk';
4
+ import { TngSortHeader, TngTable, TngTableBody, TngTableCell, TngTableCellOutlet, TngTableCellTpl, TngTableColumn, TngTableColumnResizer, TngTableColumnSizing, createTngTableIntlDateFormatter, createTngTableIntlNumberFormatter, TngTableEmpty, TngTableError, TngTableExpansion, TngTableFooter, TngTableFooterOutlet, TngTableFooterTpl, TngTableHeader, TngTableHeaderCell, TngTableHeaderOutlet, TngTableHeaderTpl, TngTableLoading, TngTablePagination, TngTableRow, TngTableRowExpander, TngTableSelection, TngTableScrollContainer, TngTableVirtual, TngTableVirtualSpacer, TngTableSort, TngTableToolbar, } from '..';
5
+ import { TngPopover, TngPopoverPanel, TngPopoverTrigger, } from '../../../overlay';
6
+ import * as i0 from "@angular/core";
7
+ export function getByTestId(fixture, testId) {
8
+ const element = fixture.nativeElement.querySelector(`[data-testid="${testId}"]`);
9
+ if (element === null) {
10
+ throw new Error(`Expected element for data-testid="${testId}".`);
11
+ }
12
+ return element;
13
+ }
14
+ export function queryAllByTestId(fixture, testId) {
15
+ return Array.from(fixture.nativeElement.querySelectorAll(`[data-testid="${testId}"]`));
16
+ }
17
+ export function dispatchKeydown(element, key, init = {}) {
18
+ const event = new KeyboardEvent('keydown', {
19
+ bubbles: true,
20
+ cancelable: true,
21
+ key,
22
+ ...init,
23
+ });
24
+ element.dispatchEvent(event);
25
+ return event;
26
+ }
27
+ export function dispatchMouseEvent(element, type, init = {}) {
28
+ const event = new MouseEvent(type, {
29
+ bubbles: true,
30
+ cancelable: true,
31
+ ...init,
32
+ });
33
+ element.dispatchEvent(event);
34
+ return event;
35
+ }
36
+ function renderDynamicCell(row, columnId) {
37
+ switch (columnId) {
38
+ case 'label':
39
+ return row.label ?? '';
40
+ case 'status':
41
+ return row.status ?? '';
42
+ case 'value':
43
+ return row.value === null || row.value === undefined ? '' : String(row.value);
44
+ }
45
+ }
46
+ export class TableHarnessComponent {
47
+ ariaLabel = signal('Harness table', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
48
+ dir = signal('ltr', ...(ngDevMode ? [{ debugName: "dir" }] : []));
49
+ error = signal(false, ...(ngDevMode ? [{ debugName: "error" }] : []));
50
+ filterable = signal(false, ...(ngDevMode ? [{ debugName: "filterable" }] : []));
51
+ items = signal([
52
+ { id: 'alpha', label: 'Alpha' },
53
+ ], ...(ngDevMode ? [{ debugName: "items" }] : []));
54
+ loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
55
+ pageable = signal(false, ...(ngDevMode ? [{ debugName: "pageable" }] : []));
56
+ showFooter = signal(true, ...(ngDevMode ? [{ debugName: "showFooter" }] : []));
57
+ showHeader = signal(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
58
+ renderedItems = computed(() => this.items() ?? [], ...(ngDevMode ? [{ debugName: "renderedItems" }] : []));
59
+ tableRef;
60
+ headerRef;
61
+ bodyRef;
62
+ footerRef;
63
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
64
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, static: true }, { propertyName: "headerRef", first: true, predicate: ["headerRef"], descendants: true }, { propertyName: "bodyRef", first: true, predicate: ["bodyRef"], descendants: true, static: true }, { propertyName: "footerRef", first: true, predicate: ["footerRef"], descendants: true }], ngImport: i0, template: `
65
+ <section tngTableToolbar data-testid="toolbar">Toolbar</section>
66
+
67
+ <table
68
+ tngTable
69
+ #tableRef="tngTable"
70
+ data-testid="table"
71
+ [ariaLabel]="ariaLabel()"
72
+ [dir]="dir()"
73
+ [error]="error()"
74
+ [filterable]="filterable()"
75
+ [items]="items()"
76
+ [loading]="loading()"
77
+ [pageable]="pageable()"
78
+ >
79
+ @if (showHeader()) {
80
+ <thead tngTableHeader #headerRef="tngTableHeader" data-testid="header">
81
+ <tr tngTableRow data-testid="header-row">
82
+ <th tngTableHeaderCell data-testid="header-cell">Label</th>
83
+ </tr>
84
+ </thead>
85
+ }
86
+
87
+ <tbody tngTableBody #bodyRef="tngTableBody" data-testid="body">
88
+ @for (item of renderedItems(); track item.id) {
89
+ <tr tngTableRow data-testid="body-row">
90
+ <td tngTableCell data-testid="body-cell">{{ item.label }}</td>
91
+ </tr>
92
+ }
93
+ </tbody>
94
+
95
+ @if (showFooter()) {
96
+ <tfoot tngTableFooter #footerRef="tngTableFooter" data-testid="footer">
97
+ <tr tngTableRow data-testid="footer-row">
98
+ <td tngTableCell data-testid="footer-cell">Footer</td>
99
+ </tr>
100
+ </tfoot>
101
+ }
102
+ </table>
103
+
104
+ @if (loading()) {
105
+ <div data-testid="loading-slot" tngTableLoading>Loading</div>
106
+ }
107
+
108
+ @if (!loading() && renderedItems().length === 0) {
109
+ <div data-testid="empty-slot" tngTableEmpty>Empty</div>
110
+ }
111
+
112
+ @if (error()) {
113
+ <div data-testid="error-slot" tngTableError>Error</div>
114
+ }
115
+
116
+ <nav tngTablePagination data-testid="pagination">Pagination</nav>
117
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableFooter, selector: "tfoot[tngTableFooter]", inputs: ["tngTableFooterSticky", "tngTableFooterStickyOffset"], exportAs: ["tngTableFooter"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableToolbar, selector: "[tngTableToolbar]", exportAs: ["tngTableToolbar"] }, { kind: "directive", type: TngTableLoading, selector: "[tngTableLoading]", exportAs: ["tngTableLoading"] }, { kind: "directive", type: TngTableEmpty, selector: "[tngTableEmpty]", exportAs: ["tngTableEmpty"] }, { kind: "directive", type: TngTableError, selector: "[tngTableError]", exportAs: ["tngTableError"] }, { kind: "directive", type: TngTablePagination, selector: "[tngTablePagination]", exportAs: ["tngTablePagination"] }] });
118
+ }
119
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableHarnessComponent, decorators: [{
120
+ type: Component,
121
+ args: [{
122
+ imports: [
123
+ TngTable,
124
+ TngTableHeader,
125
+ TngTableBody,
126
+ TngTableFooter,
127
+ TngTableRow,
128
+ TngTableHeaderCell,
129
+ TngTableCell,
130
+ TngTableToolbar,
131
+ TngTableLoading,
132
+ TngTableEmpty,
133
+ TngTableError,
134
+ TngTablePagination,
135
+ ],
136
+ template: `
137
+ <section tngTableToolbar data-testid="toolbar">Toolbar</section>
138
+
139
+ <table
140
+ tngTable
141
+ #tableRef="tngTable"
142
+ data-testid="table"
143
+ [ariaLabel]="ariaLabel()"
144
+ [dir]="dir()"
145
+ [error]="error()"
146
+ [filterable]="filterable()"
147
+ [items]="items()"
148
+ [loading]="loading()"
149
+ [pageable]="pageable()"
150
+ >
151
+ @if (showHeader()) {
152
+ <thead tngTableHeader #headerRef="tngTableHeader" data-testid="header">
153
+ <tr tngTableRow data-testid="header-row">
154
+ <th tngTableHeaderCell data-testid="header-cell">Label</th>
155
+ </tr>
156
+ </thead>
157
+ }
158
+
159
+ <tbody tngTableBody #bodyRef="tngTableBody" data-testid="body">
160
+ @for (item of renderedItems(); track item.id) {
161
+ <tr tngTableRow data-testid="body-row">
162
+ <td tngTableCell data-testid="body-cell">{{ item.label }}</td>
163
+ </tr>
164
+ }
165
+ </tbody>
166
+
167
+ @if (showFooter()) {
168
+ <tfoot tngTableFooter #footerRef="tngTableFooter" data-testid="footer">
169
+ <tr tngTableRow data-testid="footer-row">
170
+ <td tngTableCell data-testid="footer-cell">Footer</td>
171
+ </tr>
172
+ </tfoot>
173
+ }
174
+ </table>
175
+
176
+ @if (loading()) {
177
+ <div data-testid="loading-slot" tngTableLoading>Loading</div>
178
+ }
179
+
180
+ @if (!loading() && renderedItems().length === 0) {
181
+ <div data-testid="empty-slot" tngTableEmpty>Empty</div>
182
+ }
183
+
184
+ @if (error()) {
185
+ <div data-testid="error-slot" tngTableError>Error</div>
186
+ }
187
+
188
+ <nav tngTablePagination data-testid="pagination">Pagination</nav>
189
+ `,
190
+ }]
191
+ }], propDecorators: { tableRef: [{
192
+ type: ViewChild,
193
+ args: ['tableRef', { static: true }]
194
+ }], headerRef: [{
195
+ type: ViewChild,
196
+ args: ['headerRef']
197
+ }], bodyRef: [{
198
+ type: ViewChild,
199
+ args: ['bodyRef', { static: true }]
200
+ }], footerRef: [{
201
+ type: ViewChild,
202
+ args: ['footerRef']
203
+ }] } });
204
+ export class TableSortHarnessComponent {
205
+ activeColumnId = signal(undefined, ...(ngDevMode ? [{ debugName: "activeColumnId" }] : []));
206
+ controlled = signal(false, ...(ngDevMode ? [{ debugName: "controlled" }] : []));
207
+ direction = signal(undefined, ...(ngDevMode ? [{ debugName: "direction" }] : []));
208
+ headerDisabled = signal(false, ...(ngDevMode ? [{ debugName: "headerDisabled" }] : []));
209
+ showHeader = signal(true, ...(ngDevMode ? [{ debugName: "showHeader" }] : []));
210
+ sortRef;
211
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSortHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
212
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableSortHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "sortRef", first: true, predicate: ["sortRef"], descendants: true }], ngImport: i0, template: `
213
+ @if (controlled()) {
214
+ <table
215
+ tngTable
216
+ tngTableSort
217
+ #sortRef="tngTableSort"
218
+ data-testid="table"
219
+ [tngTableSortActive]="activeColumnId()"
220
+ [tngTableSortDirection]="direction()"
221
+ >
222
+ @if (showHeader()) {
223
+ <thead tngTableHeader data-testid="header">
224
+ <tr tngTableRow>
225
+ <th
226
+ tngTableHeaderCell
227
+ [tngSortHeader]="'label'"
228
+ [tngSortHeaderDisabled]="headerDisabled()"
229
+ data-testid="sort-header"
230
+ >
231
+ Label
232
+ </th>
233
+ </tr>
234
+ </thead>
235
+ }
236
+
237
+ <tbody tngTableBody>
238
+ <tr tngTableRow>
239
+ <td tngTableCell>Alpha</td>
240
+ </tr>
241
+ </tbody>
242
+ </table>
243
+ } @else {
244
+ <table
245
+ tngTable
246
+ tngTableSort
247
+ #sortRef="tngTableSort"
248
+ data-testid="table"
249
+ >
250
+ @if (showHeader()) {
251
+ <thead tngTableHeader data-testid="header">
252
+ <tr tngTableRow>
253
+ <th
254
+ tngTableHeaderCell
255
+ [tngSortHeader]="'label'"
256
+ [tngSortHeaderDisabled]="headerDisabled()"
257
+ data-testid="sort-header"
258
+ >
259
+ Label
260
+ </th>
261
+ </tr>
262
+ </thead>
263
+ }
264
+
265
+ <tbody tngTableBody>
266
+ <tr tngTableRow>
267
+ <td tngTableCell>Alpha</td>
268
+ </tr>
269
+ </tbody>
270
+ </table>
271
+ }
272
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableSort, selector: "[tngTableSort]", inputs: ["tngTableSortActive", "tngTableSortDirection", "tngTableSortDisableClear"], outputs: ["sortChange"], exportAs: ["tngTableSort"] }, { kind: "directive", type: TngSortHeader, selector: "th[tngSortHeader]", inputs: ["tngSortHeader", "tngSortHeaderDisabled"], exportAs: ["tngSortHeader"] }] });
273
+ }
274
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSortHarnessComponent, decorators: [{
275
+ type: Component,
276
+ args: [{
277
+ imports: [
278
+ TngTable,
279
+ TngTableHeader,
280
+ TngTableBody,
281
+ TngTableRow,
282
+ TngTableHeaderCell,
283
+ TngTableCell,
284
+ TngTableSort,
285
+ TngSortHeader,
286
+ ],
287
+ template: `
288
+ @if (controlled()) {
289
+ <table
290
+ tngTable
291
+ tngTableSort
292
+ #sortRef="tngTableSort"
293
+ data-testid="table"
294
+ [tngTableSortActive]="activeColumnId()"
295
+ [tngTableSortDirection]="direction()"
296
+ >
297
+ @if (showHeader()) {
298
+ <thead tngTableHeader data-testid="header">
299
+ <tr tngTableRow>
300
+ <th
301
+ tngTableHeaderCell
302
+ [tngSortHeader]="'label'"
303
+ [tngSortHeaderDisabled]="headerDisabled()"
304
+ data-testid="sort-header"
305
+ >
306
+ Label
307
+ </th>
308
+ </tr>
309
+ </thead>
310
+ }
311
+
312
+ <tbody tngTableBody>
313
+ <tr tngTableRow>
314
+ <td tngTableCell>Alpha</td>
315
+ </tr>
316
+ </tbody>
317
+ </table>
318
+ } @else {
319
+ <table
320
+ tngTable
321
+ tngTableSort
322
+ #sortRef="tngTableSort"
323
+ data-testid="table"
324
+ >
325
+ @if (showHeader()) {
326
+ <thead tngTableHeader data-testid="header">
327
+ <tr tngTableRow>
328
+ <th
329
+ tngTableHeaderCell
330
+ [tngSortHeader]="'label'"
331
+ [tngSortHeaderDisabled]="headerDisabled()"
332
+ data-testid="sort-header"
333
+ >
334
+ Label
335
+ </th>
336
+ </tr>
337
+ </thead>
338
+ }
339
+
340
+ <tbody tngTableBody>
341
+ <tr tngTableRow>
342
+ <td tngTableCell>Alpha</td>
343
+ </tr>
344
+ </tbody>
345
+ </table>
346
+ }
347
+ `,
348
+ }]
349
+ }], propDecorators: { sortRef: [{
350
+ type: ViewChild,
351
+ args: ['sortRef']
352
+ }] } });
353
+ export class TableSelectionHarnessComponent {
354
+ hiddenIds = signal([], ...(ngDevMode ? [{ debugName: "hiddenIds" }] : []));
355
+ rows = signal([
356
+ { id: 'alpha', label: 'Alpha' },
357
+ { id: 'beta', label: 'Beta' },
358
+ { disabled: true, id: 'gamma', label: 'Gamma' },
359
+ { id: 'delta', label: 'Delta' },
360
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
361
+ selectedIds = signal([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
362
+ selectionMode = signal('single', ...(ngDevMode ? [{ debugName: "selectionMode" }] : []));
363
+ selectionEvents = [];
364
+ visibleRows = computed(() => this.rows().filter((row) => !this.hiddenIds().includes(row.id)), ...(ngDevMode ? [{ debugName: "visibleRows" }] : []));
365
+ selectionRef;
366
+ onSelectionChange(event) {
367
+ this.selectedIds.set(event.selectedIds);
368
+ this.selectionEvents.push(event);
369
+ }
370
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSelectionHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
371
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableSelectionHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "selectionRef", first: true, predicate: ["selectionRef"], descendants: true, static: true }], ngImport: i0, template: `
372
+ <table
373
+ tngTable
374
+ tngTableSelection
375
+ #selectionRef="tngTableSelection"
376
+ data-testid="selection-table"
377
+ [tngTableSelectedIds]="selectedIds()"
378
+ [tngTableSelectionMode]="selectionMode()"
379
+ (selectionChange)="onSelectionChange($event)"
380
+ >
381
+ <thead tngTableHeader>
382
+ <tr tngTableRow>
383
+ <th tngTableHeaderCell [tngTableColumnId]="'label'" data-testid="selection-header">
384
+ Label
385
+ </th>
386
+ </tr>
387
+ </thead>
388
+
389
+ <tbody tngTableBody>
390
+ @for (row of visibleRows(); track row.id) {
391
+ <tr
392
+ tngTableRow
393
+ [attr.data-testid]="'selection-row-' + row.id"
394
+ [tngTableRowDisabled]="row.disabled ?? false"
395
+ [tngTableRowId]="row.id"
396
+ >
397
+ <td
398
+ tngTableCell
399
+ [attr.data-testid]="'selection-cell-' + row.id"
400
+ [tngTableColumnId]="'label'"
401
+ >
402
+ {{ row.label }}
403
+ </td>
404
+ </tr>
405
+ }
406
+ </tbody>
407
+ </table>
408
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableSelection, selector: "table[tngTable][tngTableSelection]", inputs: ["tngTableSelectionMode", "tngTableSelectedIds"], outputs: ["selectionChange"], exportAs: ["tngTableSelection"] }] });
409
+ }
410
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSelectionHarnessComponent, decorators: [{
411
+ type: Component,
412
+ args: [{
413
+ imports: [
414
+ TngTable,
415
+ TngTableBody,
416
+ TngTableCell,
417
+ TngTableHeader,
418
+ TngTableHeaderCell,
419
+ TngTableRow,
420
+ TngTableSelection,
421
+ ],
422
+ template: `
423
+ <table
424
+ tngTable
425
+ tngTableSelection
426
+ #selectionRef="tngTableSelection"
427
+ data-testid="selection-table"
428
+ [tngTableSelectedIds]="selectedIds()"
429
+ [tngTableSelectionMode]="selectionMode()"
430
+ (selectionChange)="onSelectionChange($event)"
431
+ >
432
+ <thead tngTableHeader>
433
+ <tr tngTableRow>
434
+ <th tngTableHeaderCell [tngTableColumnId]="'label'" data-testid="selection-header">
435
+ Label
436
+ </th>
437
+ </tr>
438
+ </thead>
439
+
440
+ <tbody tngTableBody>
441
+ @for (row of visibleRows(); track row.id) {
442
+ <tr
443
+ tngTableRow
444
+ [attr.data-testid]="'selection-row-' + row.id"
445
+ [tngTableRowDisabled]="row.disabled ?? false"
446
+ [tngTableRowId]="row.id"
447
+ >
448
+ <td
449
+ tngTableCell
450
+ [attr.data-testid]="'selection-cell-' + row.id"
451
+ [tngTableColumnId]="'label'"
452
+ >
453
+ {{ row.label }}
454
+ </td>
455
+ </tr>
456
+ }
457
+ </tbody>
458
+ </table>
459
+ `,
460
+ }]
461
+ }], propDecorators: { selectionRef: [{
462
+ type: ViewChild,
463
+ args: ['selectionRef', { static: true }]
464
+ }] } });
465
+ export class TableExpansionHarnessComponent {
466
+ expandedIds = signal([], ...(ngDevMode ? [{ debugName: "expandedIds" }] : []));
467
+ expansionEvents = [];
468
+ expansionMode = signal('multiple', ...(ngDevMode ? [{ debugName: "expansionMode" }] : []));
469
+ rows = signal([
470
+ { id: 'alpha', label: 'Alpha', status: 'Ready', value: 1 },
471
+ { id: 'beta', label: 'Beta', status: 'Review', value: 2 },
472
+ { id: 'gamma', label: 'Gamma', status: 'Draft', value: 3 },
473
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
474
+ visibleColumns = signal([
475
+ { id: 'label', label: 'Label' },
476
+ { id: 'status', label: 'Status' },
477
+ { id: 'value', label: 'Value' },
478
+ ], ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
479
+ expansionRef;
480
+ isExpanded(rowId) {
481
+ return this.expandedIds().includes(rowId);
482
+ }
483
+ onExpansionChange(event) {
484
+ this.expandedIds.set(event.expandedIds);
485
+ this.expansionEvents.push(event);
486
+ }
487
+ renderCell(row, columnId) {
488
+ return renderDynamicCell(row, columnId);
489
+ }
490
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableExpansionHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
491
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableExpansionHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "expansionRef", first: true, predicate: ["expansionRef"], descendants: true, static: true }], ngImport: i0, template: `
492
+ <table
493
+ tngTable
494
+ tngTableExpansion
495
+ #expansionRef="tngTableExpansion"
496
+ data-testid="expansion-table"
497
+ [tngTableExpandedIds]="expandedIds()"
498
+ [tngTableExpansionMode]="expansionMode()"
499
+ (expansionChange)="onExpansionChange($event)"
500
+ >
501
+ <thead tngTableHeader>
502
+ <tr tngTableRow>
503
+ <th tngTableHeaderCell data-testid="expander-header">Expand</th>
504
+ @for (column of visibleColumns(); track column.id) {
505
+ <th
506
+ tngTableHeaderCell
507
+ [attr.data-testid]="'expansion-header-' + column.id"
508
+ [tngTableColumnId]="column.id"
509
+ >
510
+ {{ column.label }}
511
+ </th>
512
+ }
513
+ </tr>
514
+ </thead>
515
+
516
+ <tbody tngTableBody>
517
+ @for (row of rows(); track row.id) {
518
+ <tr
519
+ tngTableRow
520
+ [attr.data-testid]="'expansion-row-' + row.id"
521
+ [tngTableRowId]="row.id"
522
+ >
523
+ <td tngTableCell [tngTableColumnId]="'label'">
524
+ <div
525
+ tabindex="0"
526
+ [attr.data-testid]="'expander-' + row.id"
527
+ [tngTableRowExpander]="row.id"
528
+ >
529
+ Toggle
530
+ </div>
531
+ </td>
532
+ @for (column of visibleColumns(); track column.id) {
533
+ <td
534
+ tngTableCell
535
+ [attr.data-testid]="'expansion-cell-' + row.id + '-' + column.id"
536
+ [tngTableColumnId]="column.id"
537
+ >
538
+ {{ renderCell(row, column.id) }}
539
+ </td>
540
+ }
541
+ </tr>
542
+
543
+ @if (isExpanded(row.id)) {
544
+ <tr
545
+ tngTableRow
546
+ [attr.data-testid]="'detail-row-' + row.id"
547
+ [tngTableRowExpanded]="true"
548
+ [tngTableRowId]="row.id + '-detail'"
549
+ >
550
+ <td
551
+ tngTableCell
552
+ [attr.colspan]="visibleColumns().length + 1"
553
+ [attr.data-testid]="'detail-cell-' + row.id"
554
+ >
555
+ Details for {{ row.label }}
556
+ </td>
557
+ </tr>
558
+ }
559
+ }
560
+ </tbody>
561
+ </table>
562
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableExpansion, selector: "table[tngTable][tngTableExpansion]", inputs: ["tngTableExpandedIds", "tngTableExpansionMode"], outputs: ["expansionChange"], exportAs: ["tngTableExpansion"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableRowExpander, selector: "[tngTableRowExpander]", inputs: ["tngTableRowExpander"], exportAs: ["tngTableRowExpander"] }] });
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableExpansionHarnessComponent, decorators: [{
565
+ type: Component,
566
+ args: [{
567
+ imports: [
568
+ TngTable,
569
+ TngTableBody,
570
+ TngTableCell,
571
+ TngTableExpansion,
572
+ TngTableHeader,
573
+ TngTableHeaderCell,
574
+ TngTableRow,
575
+ TngTableRowExpander,
576
+ ],
577
+ template: `
578
+ <table
579
+ tngTable
580
+ tngTableExpansion
581
+ #expansionRef="tngTableExpansion"
582
+ data-testid="expansion-table"
583
+ [tngTableExpandedIds]="expandedIds()"
584
+ [tngTableExpansionMode]="expansionMode()"
585
+ (expansionChange)="onExpansionChange($event)"
586
+ >
587
+ <thead tngTableHeader>
588
+ <tr tngTableRow>
589
+ <th tngTableHeaderCell data-testid="expander-header">Expand</th>
590
+ @for (column of visibleColumns(); track column.id) {
591
+ <th
592
+ tngTableHeaderCell
593
+ [attr.data-testid]="'expansion-header-' + column.id"
594
+ [tngTableColumnId]="column.id"
595
+ >
596
+ {{ column.label }}
597
+ </th>
598
+ }
599
+ </tr>
600
+ </thead>
601
+
602
+ <tbody tngTableBody>
603
+ @for (row of rows(); track row.id) {
604
+ <tr
605
+ tngTableRow
606
+ [attr.data-testid]="'expansion-row-' + row.id"
607
+ [tngTableRowId]="row.id"
608
+ >
609
+ <td tngTableCell [tngTableColumnId]="'label'">
610
+ <div
611
+ tabindex="0"
612
+ [attr.data-testid]="'expander-' + row.id"
613
+ [tngTableRowExpander]="row.id"
614
+ >
615
+ Toggle
616
+ </div>
617
+ </td>
618
+ @for (column of visibleColumns(); track column.id) {
619
+ <td
620
+ tngTableCell
621
+ [attr.data-testid]="'expansion-cell-' + row.id + '-' + column.id"
622
+ [tngTableColumnId]="column.id"
623
+ >
624
+ {{ renderCell(row, column.id) }}
625
+ </td>
626
+ }
627
+ </tr>
628
+
629
+ @if (isExpanded(row.id)) {
630
+ <tr
631
+ tngTableRow
632
+ [attr.data-testid]="'detail-row-' + row.id"
633
+ [tngTableRowExpanded]="true"
634
+ [tngTableRowId]="row.id + '-detail'"
635
+ >
636
+ <td
637
+ tngTableCell
638
+ [attr.colspan]="visibleColumns().length + 1"
639
+ [attr.data-testid]="'detail-cell-' + row.id"
640
+ >
641
+ Details for {{ row.label }}
642
+ </td>
643
+ </tr>
644
+ }
645
+ }
646
+ </tbody>
647
+ </table>
648
+ `,
649
+ }]
650
+ }], propDecorators: { expansionRef: [{
651
+ type: ViewChild,
652
+ args: ['expansionRef', { static: true }]
653
+ }] } });
654
+ export class TableInteractionHarnessComponent {
655
+ cellClicks = [];
656
+ rowClicks = [];
657
+ rowContextMenus = [];
658
+ rows = signal([
659
+ { id: 'alpha', label: 'Alpha' },
660
+ { id: 'beta', label: 'Beta' },
661
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
662
+ onCellClick(event) {
663
+ this.cellClicks.push(event);
664
+ }
665
+ onRowClick(event) {
666
+ this.rowClicks.push(event);
667
+ }
668
+ onRowContextMenu(event) {
669
+ this.rowContextMenus.push(event);
670
+ }
671
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableInteractionHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
672
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableInteractionHarnessComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
673
+ <table tngTable data-testid="interaction-table">
674
+ <thead tngTableHeader>
675
+ <tr tngTableRow>
676
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
677
+ <th tngTableHeaderCell [tngTableColumnId]="'actions'">Actions</th>
678
+ </tr>
679
+ </thead>
680
+
681
+ <tbody tngTableBody>
682
+ @for (row of rows(); track row.id) {
683
+ <tr
684
+ tngTableRow
685
+ [attr.data-testid]="'interaction-row-' + row.id"
686
+ [tngTableRowId]="row.id"
687
+ (rowClick)="onRowClick($event)"
688
+ (rowContextMenu)="onRowContextMenu($event)"
689
+ >
690
+ <td
691
+ tngTableCell
692
+ [attr.data-testid]="'interaction-cell-' + row.id"
693
+ [tngTableColumnId]="'label'"
694
+ (cellClick)="onCellClick($event)"
695
+ >
696
+ {{ row.label }}
697
+ </td>
698
+ <td
699
+ tngTableCell
700
+ [tngTableColumnId]="'actions'"
701
+ (cellClick)="onCellClick($event)"
702
+ >
703
+ <button
704
+ type="button"
705
+ [attr.data-testid]="'row-action-' + row.id"
706
+ (click)="$event.stopPropagation()"
707
+ >
708
+ Action
709
+ </button>
710
+ </td>
711
+ </tr>
712
+ }
713
+ </tbody>
714
+ </table>
715
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }] });
716
+ }
717
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableInteractionHarnessComponent, decorators: [{
718
+ type: Component,
719
+ args: [{
720
+ imports: [
721
+ TngTable,
722
+ TngTableBody,
723
+ TngTableCell,
724
+ TngTableHeader,
725
+ TngTableHeaderCell,
726
+ TngTableRow,
727
+ ],
728
+ template: `
729
+ <table tngTable data-testid="interaction-table">
730
+ <thead tngTableHeader>
731
+ <tr tngTableRow>
732
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
733
+ <th tngTableHeaderCell [tngTableColumnId]="'actions'">Actions</th>
734
+ </tr>
735
+ </thead>
736
+
737
+ <tbody tngTableBody>
738
+ @for (row of rows(); track row.id) {
739
+ <tr
740
+ tngTableRow
741
+ [attr.data-testid]="'interaction-row-' + row.id"
742
+ [tngTableRowId]="row.id"
743
+ (rowClick)="onRowClick($event)"
744
+ (rowContextMenu)="onRowContextMenu($event)"
745
+ >
746
+ <td
747
+ tngTableCell
748
+ [attr.data-testid]="'interaction-cell-' + row.id"
749
+ [tngTableColumnId]="'label'"
750
+ (cellClick)="onCellClick($event)"
751
+ >
752
+ {{ row.label }}
753
+ </td>
754
+ <td
755
+ tngTableCell
756
+ [tngTableColumnId]="'actions'"
757
+ (cellClick)="onCellClick($event)"
758
+ >
759
+ <button
760
+ type="button"
761
+ [attr.data-testid]="'row-action-' + row.id"
762
+ (click)="$event.stopPropagation()"
763
+ >
764
+ Action
765
+ </button>
766
+ </td>
767
+ </tr>
768
+ }
769
+ </tbody>
770
+ </table>
771
+ `,
772
+ }]
773
+ }] });
774
+ export class TableEmbeddedIntegrationHarnessComponent {
775
+ cellClicks = [];
776
+ rowClicks = [];
777
+ rows = signal([
778
+ { id: 'alpha', label: 'Alpha', status: 'ready' },
779
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
780
+ selectedIds = signal([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
781
+ onCellClick(event) {
782
+ this.cellClicks.push(event);
783
+ }
784
+ onRowClick(event) {
785
+ this.rowClicks.push(event);
786
+ }
787
+ onSelectionChange(event) {
788
+ this.selectedIds.set(event.selectedIds);
789
+ }
790
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableEmbeddedIntegrationHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
791
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableEmbeddedIntegrationHarnessComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
792
+ <table
793
+ tngTable
794
+ tngTableSelection
795
+ data-testid="integration-table"
796
+ [tngTableSelectedIds]="selectedIds()"
797
+ (selectionChange)="onSelectionChange($event)"
798
+ >
799
+ <thead tngTableHeader>
800
+ <tr tngTableRow>
801
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
802
+ <th tngTableHeaderCell [tngTableColumnId]="'link'">Link</th>
803
+ <th tngTableHeaderCell [tngTableColumnId]="'form'">Form</th>
804
+ <th tngTableHeaderCell [tngTableColumnId]="'overlay'">Overlay</th>
805
+ </tr>
806
+ </thead>
807
+
808
+ <tbody tngTableBody>
809
+ @for (row of rows(); track row.id) {
810
+ <tr
811
+ tngTableRow
812
+ [attr.data-testid]="'integration-row-' + row.id"
813
+ [tngTableRowId]="row.id"
814
+ (rowClick)="onRowClick($event)"
815
+ >
816
+ <td
817
+ tngTableCell
818
+ [attr.data-testid]="'integration-cell-' + row.id + '-label'"
819
+ [tngTableColumnId]="'label'"
820
+ (cellClick)="onCellClick($event)"
821
+ >
822
+ {{ row.label }}
823
+ </td>
824
+
825
+ <td
826
+ tngTableCell
827
+ [attr.data-testid]="'integration-cell-' + row.id + '-link'"
828
+ [tngTableColumnId]="'link'"
829
+ (cellClick)="onCellClick($event)"
830
+ >
831
+ <a [routerLink]="['/detail', row.id]" [attr.data-testid]="'integration-link-' + row.id">
832
+ Open
833
+ </a>
834
+ </td>
835
+
836
+ <td
837
+ tngTableCell
838
+ [attr.data-testid]="'integration-cell-' + row.id + '-form'"
839
+ [tngTableColumnId]="'form'"
840
+ (cellClick)="onCellClick($event)"
841
+ >
842
+ <input
843
+ type="text"
844
+ [attr.data-testid]="'integration-input-' + row.id"
845
+ [value]="row.label"
846
+ />
847
+ <select [attr.data-testid]="'integration-select-' + row.id">
848
+ <option value="draft">Draft</option>
849
+ <option value="ready">Ready</option>
850
+ </select>
851
+ </td>
852
+
853
+ <td
854
+ tngTableCell
855
+ [attr.data-testid]="'integration-cell-' + row.id + '-overlay'"
856
+ [tngTableColumnId]="'overlay'"
857
+ (cellClick)="onCellClick($event)"
858
+ >
859
+ <section tngPopover #popover="tngPopover" [restoreFocus]="false">
860
+ <button
861
+ type="button"
862
+ [attr.data-testid]="'integration-popover-trigger-' + row.id"
863
+ [tngPopoverTrigger]="popover"
864
+ >
865
+ Actions
866
+ </button>
867
+
868
+ <section tngPopoverPanel [attr.data-testid]="'integration-popover-panel-' + row.id">
869
+ <button type="button">Inspect</button>
870
+ </section>
871
+ </section>
872
+ </td>
873
+ </tr>
874
+ }
875
+ </tbody>
876
+ </table>
877
+ `, isInline: true, dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: TngPopover, selector: "[tngPopover]", inputs: ["open", "defaultOpen", "disabled", "closeOnEscape", "closeOnOutsidePointer", "restoreFocus", "autoFocus", "side", "align", "panelRole", "ariaHasPopup", "ariaLabel"], outputs: ["openChange", "closed"], exportAs: ["tngPopover"] }, { kind: "directive", type: TngPopoverPanel, selector: "[tngPopoverPanel], [tngPopoverContent]", exportAs: ["tngPopoverPanel"] }, { kind: "directive", type: TngPopoverTrigger, selector: "[tngPopoverTrigger]", inputs: ["tngPopoverTrigger"], exportAs: ["tngPopoverTrigger"] }, { kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableSelection, selector: "table[tngTable][tngTableSelection]", inputs: ["tngTableSelectionMode", "tngTableSelectedIds"], outputs: ["selectionChange"], exportAs: ["tngTableSelection"] }] });
878
+ }
879
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableEmbeddedIntegrationHarnessComponent, decorators: [{
880
+ type: Component,
881
+ args: [{
882
+ imports: [
883
+ RouterLink,
884
+ TngPopover,
885
+ TngPopoverPanel,
886
+ TngPopoverTrigger,
887
+ TngTable,
888
+ TngTableBody,
889
+ TngTableCell,
890
+ TngTableHeader,
891
+ TngTableHeaderCell,
892
+ TngTableRow,
893
+ TngTableSelection,
894
+ ],
895
+ template: `
896
+ <table
897
+ tngTable
898
+ tngTableSelection
899
+ data-testid="integration-table"
900
+ [tngTableSelectedIds]="selectedIds()"
901
+ (selectionChange)="onSelectionChange($event)"
902
+ >
903
+ <thead tngTableHeader>
904
+ <tr tngTableRow>
905
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
906
+ <th tngTableHeaderCell [tngTableColumnId]="'link'">Link</th>
907
+ <th tngTableHeaderCell [tngTableColumnId]="'form'">Form</th>
908
+ <th tngTableHeaderCell [tngTableColumnId]="'overlay'">Overlay</th>
909
+ </tr>
910
+ </thead>
911
+
912
+ <tbody tngTableBody>
913
+ @for (row of rows(); track row.id) {
914
+ <tr
915
+ tngTableRow
916
+ [attr.data-testid]="'integration-row-' + row.id"
917
+ [tngTableRowId]="row.id"
918
+ (rowClick)="onRowClick($event)"
919
+ >
920
+ <td
921
+ tngTableCell
922
+ [attr.data-testid]="'integration-cell-' + row.id + '-label'"
923
+ [tngTableColumnId]="'label'"
924
+ (cellClick)="onCellClick($event)"
925
+ >
926
+ {{ row.label }}
927
+ </td>
928
+
929
+ <td
930
+ tngTableCell
931
+ [attr.data-testid]="'integration-cell-' + row.id + '-link'"
932
+ [tngTableColumnId]="'link'"
933
+ (cellClick)="onCellClick($event)"
934
+ >
935
+ <a [routerLink]="['/detail', row.id]" [attr.data-testid]="'integration-link-' + row.id">
936
+ Open
937
+ </a>
938
+ </td>
939
+
940
+ <td
941
+ tngTableCell
942
+ [attr.data-testid]="'integration-cell-' + row.id + '-form'"
943
+ [tngTableColumnId]="'form'"
944
+ (cellClick)="onCellClick($event)"
945
+ >
946
+ <input
947
+ type="text"
948
+ [attr.data-testid]="'integration-input-' + row.id"
949
+ [value]="row.label"
950
+ />
951
+ <select [attr.data-testid]="'integration-select-' + row.id">
952
+ <option value="draft">Draft</option>
953
+ <option value="ready">Ready</option>
954
+ </select>
955
+ </td>
956
+
957
+ <td
958
+ tngTableCell
959
+ [attr.data-testid]="'integration-cell-' + row.id + '-overlay'"
960
+ [tngTableColumnId]="'overlay'"
961
+ (cellClick)="onCellClick($event)"
962
+ >
963
+ <section tngPopover #popover="tngPopover" [restoreFocus]="false">
964
+ <button
965
+ type="button"
966
+ [attr.data-testid]="'integration-popover-trigger-' + row.id"
967
+ [tngPopoverTrigger]="popover"
968
+ >
969
+ Actions
970
+ </button>
971
+
972
+ <section tngPopoverPanel [attr.data-testid]="'integration-popover-panel-' + row.id">
973
+ <button type="button">Inspect</button>
974
+ </section>
975
+ </section>
976
+ </td>
977
+ </tr>
978
+ }
979
+ </tbody>
980
+ </table>
981
+ `,
982
+ }]
983
+ }] });
984
+ export class TableControlledIntegrationHarnessComponent {
985
+ activeColumnId = signal(null, ...(ngDevMode ? [{ debugName: "activeColumnId" }] : []));
986
+ direction = signal(null, ...(ngDevMode ? [{ debugName: "direction" }] : []));
987
+ pageIndex = signal(0, ...(ngDevMode ? [{ debugName: "pageIndex" }] : []));
988
+ pageSize = signal(2, ...(ngDevMode ? [{ debugName: "pageSize" }] : []));
989
+ query = signal('', ...(ngDevMode ? [{ debugName: "query" }] : []));
990
+ rows = signal([
991
+ { id: 'gamma', label: 'Gamma', status: 'draft' },
992
+ { id: 'alpha', label: 'Alpha', status: 'ready' },
993
+ { id: 'beta', label: 'Beta', status: 'ready' },
994
+ { id: 'delta', label: 'Delta', status: 'draft' },
995
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
996
+ sortEvents = [];
997
+ filteredRows = computed(() => createTngFilterController({
998
+ globalFilter: (item, query) => item.label.toLowerCase().includes(query.toLowerCase()),
999
+ query: this.query(),
1000
+ }).apply(this.rows()), ...(ngDevMode ? [{ debugName: "filteredRows" }] : []));
1001
+ sortedRows = computed(() => createTngSortController({
1002
+ accessor: (item, columnId) => item[columnId],
1003
+ activeColumnId: this.activeColumnId() === 'label' ? 'label' : null,
1004
+ direction: this.direction(),
1005
+ }).apply(this.filteredRows()), ...(ngDevMode ? [{ debugName: "sortedRows" }] : []));
1006
+ visibleRows = computed(() => createTngPaginationController({
1007
+ pageIndex: this.pageIndex(),
1008
+ pageSize: this.pageSize(),
1009
+ }).slice(this.sortedRows()), ...(ngDevMode ? [{ debugName: "visibleRows" }] : []));
1010
+ sortRef;
1011
+ nextPage() {
1012
+ this.pageIndex.update((value) => value + 1);
1013
+ }
1014
+ onQueryInput(query) {
1015
+ this.query.set(query);
1016
+ this.pageIndex.set(0);
1017
+ }
1018
+ onSortChange(event) {
1019
+ this.activeColumnId.set(event.activeColumnId);
1020
+ this.direction.set(event.direction);
1021
+ this.pageIndex.set(0);
1022
+ this.sortEvents.push(event);
1023
+ }
1024
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableControlledIntegrationHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1025
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableControlledIntegrationHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "sortRef", first: true, predicate: ["sortRef"], descendants: true }], ngImport: i0, template: `
1026
+ <input
1027
+ #filterInput
1028
+ type="text"
1029
+ data-testid="controlled-filter"
1030
+ [value]="query()"
1031
+ (input)="onQueryInput(filterInput.value)"
1032
+ />
1033
+ <button type="button" data-testid="controlled-page-next" (click)="nextPage()">Next page</button>
1034
+
1035
+ <table
1036
+ tngTable
1037
+ tngTableSort
1038
+ #sortRef="tngTableSort"
1039
+ data-testid="controlled-table"
1040
+ [items]="visibleRows()"
1041
+ [filterable]="true"
1042
+ [pageable]="true"
1043
+ [tngTableSortActive]="activeColumnId()"
1044
+ [tngTableSortDirection]="direction()"
1045
+ (sortChange)="onSortChange($event)"
1046
+ >
1047
+ <thead tngTableHeader>
1048
+ <tr tngTableRow>
1049
+ <th
1050
+ tngTableHeaderCell
1051
+ [tngSortHeader]="'label'"
1052
+ data-testid="controlled-sort-header"
1053
+ >
1054
+ Label
1055
+ </th>
1056
+ <th tngTableHeaderCell [tngTableColumnId]="'status'">Status</th>
1057
+ </tr>
1058
+ </thead>
1059
+
1060
+ <tbody tngTableBody>
1061
+ @for (row of visibleRows(); track row.id) {
1062
+ <tr
1063
+ tngTableRow
1064
+ [attr.data-testid]="'controlled-row-' + row.id"
1065
+ [tngTableRowId]="row.id"
1066
+ >
1067
+ <td tngTableCell [tngTableColumnId]="'label'">{{ row.label }}</td>
1068
+ <td tngTableCell [tngTableColumnId]="'status'">{{ row.status }}</td>
1069
+ </tr>
1070
+ }
1071
+ </tbody>
1072
+ </table>
1073
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngSortHeader, selector: "th[tngSortHeader]", inputs: ["tngSortHeader", "tngSortHeaderDisabled"], exportAs: ["tngSortHeader"] }, { kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableSort, selector: "[tngTableSort]", inputs: ["tngTableSortActive", "tngTableSortDirection", "tngTableSortDisableClear"], outputs: ["sortChange"], exportAs: ["tngTableSort"] }] });
1074
+ }
1075
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableControlledIntegrationHarnessComponent, decorators: [{
1076
+ type: Component,
1077
+ args: [{
1078
+ imports: [
1079
+ TngSortHeader,
1080
+ TngTable,
1081
+ TngTableBody,
1082
+ TngTableCell,
1083
+ TngTableHeader,
1084
+ TngTableHeaderCell,
1085
+ TngTableRow,
1086
+ TngTableSort,
1087
+ ],
1088
+ template: `
1089
+ <input
1090
+ #filterInput
1091
+ type="text"
1092
+ data-testid="controlled-filter"
1093
+ [value]="query()"
1094
+ (input)="onQueryInput(filterInput.value)"
1095
+ />
1096
+ <button type="button" data-testid="controlled-page-next" (click)="nextPage()">Next page</button>
1097
+
1098
+ <table
1099
+ tngTable
1100
+ tngTableSort
1101
+ #sortRef="tngTableSort"
1102
+ data-testid="controlled-table"
1103
+ [items]="visibleRows()"
1104
+ [filterable]="true"
1105
+ [pageable]="true"
1106
+ [tngTableSortActive]="activeColumnId()"
1107
+ [tngTableSortDirection]="direction()"
1108
+ (sortChange)="onSortChange($event)"
1109
+ >
1110
+ <thead tngTableHeader>
1111
+ <tr tngTableRow>
1112
+ <th
1113
+ tngTableHeaderCell
1114
+ [tngSortHeader]="'label'"
1115
+ data-testid="controlled-sort-header"
1116
+ >
1117
+ Label
1118
+ </th>
1119
+ <th tngTableHeaderCell [tngTableColumnId]="'status'">Status</th>
1120
+ </tr>
1121
+ </thead>
1122
+
1123
+ <tbody tngTableBody>
1124
+ @for (row of visibleRows(); track row.id) {
1125
+ <tr
1126
+ tngTableRow
1127
+ [attr.data-testid]="'controlled-row-' + row.id"
1128
+ [tngTableRowId]="row.id"
1129
+ >
1130
+ <td tngTableCell [tngTableColumnId]="'label'">{{ row.label }}</td>
1131
+ <td tngTableCell [tngTableColumnId]="'status'">{{ row.status }}</td>
1132
+ </tr>
1133
+ }
1134
+ </tbody>
1135
+ </table>
1136
+ `,
1137
+ }]
1138
+ }], propDecorators: { sortRef: [{
1139
+ type: ViewChild,
1140
+ args: ['sortRef']
1141
+ }] } });
1142
+ export class DynamicTableHarnessComponent {
1143
+ ariaLabel = signal('Dynamic table', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
1144
+ columns = signal([
1145
+ { id: 'label', label: 'Label' },
1146
+ { id: 'status', label: 'Status' },
1147
+ { id: 'value', label: 'Value' },
1148
+ ], ...(ngDevMode ? [{ debugName: "columns" }] : []));
1149
+ rows = signal([
1150
+ { id: 'alpha', label: 'Alpha', status: 'Ready', value: 1 },
1151
+ { id: 'beta', label: 'Beta', status: undefined, value: null },
1152
+ { id: 'gamma', label: 'Gamma', status: 'Draft', value: true },
1153
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
1154
+ selectedIds = signal([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
1155
+ visibleColumns = computed(() => this.columns().filter((column) => column.hidden !== true), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : []));
1156
+ onSelectionChange(event) {
1157
+ this.selectedIds.set(event.selectedIds);
1158
+ }
1159
+ renderCell(row, columnId) {
1160
+ return renderDynamicCell(row, columnId);
1161
+ }
1162
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DynamicTableHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1163
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DynamicTableHarnessComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
1164
+ <table
1165
+ tngTable
1166
+ tngTableSelection
1167
+ data-testid="dynamic-table"
1168
+ [ariaLabel]="ariaLabel()"
1169
+ [tngTableSelectedIds]="selectedIds()"
1170
+ (selectionChange)="onSelectionChange($event)"
1171
+ >
1172
+ <thead tngTableHeader>
1173
+ <tr tngTableRow>
1174
+ @for (column of visibleColumns(); track column.id) {
1175
+ <th
1176
+ tngTableHeaderCell
1177
+ [attr.data-testid]="'dynamic-header-' + column.id"
1178
+ [tngTableColumnId]="column.id"
1179
+ scope="col"
1180
+ >
1181
+ {{ column.label }}
1182
+ </th>
1183
+ }
1184
+ </tr>
1185
+ </thead>
1186
+
1187
+ <tbody tngTableBody>
1188
+ @for (row of rows(); track row.id) {
1189
+ <tr
1190
+ tngTableRow
1191
+ [attr.data-testid]="'dynamic-row-' + row.id"
1192
+ [tngTableRowId]="row.id"
1193
+ >
1194
+ @for (column of visibleColumns(); track column.id) {
1195
+ <td
1196
+ tngTableCell
1197
+ [attr.data-testid]="'dynamic-cell-' + row.id + '-' + column.id"
1198
+ [tngTableColumnId]="column.id"
1199
+ >
1200
+ {{ renderCell(row, column.id) }}
1201
+ </td>
1202
+ }
1203
+ </tr>
1204
+ }
1205
+ </tbody>
1206
+ </table>
1207
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableSelection, selector: "table[tngTable][tngTableSelection]", inputs: ["tngTableSelectionMode", "tngTableSelectedIds"], outputs: ["selectionChange"], exportAs: ["tngTableSelection"] }] });
1208
+ }
1209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DynamicTableHarnessComponent, decorators: [{
1210
+ type: Component,
1211
+ args: [{
1212
+ imports: [
1213
+ TngTable,
1214
+ TngTableBody,
1215
+ TngTableCell,
1216
+ TngTableHeader,
1217
+ TngTableHeaderCell,
1218
+ TngTableRow,
1219
+ TngTableSelection,
1220
+ ],
1221
+ template: `
1222
+ <table
1223
+ tngTable
1224
+ tngTableSelection
1225
+ data-testid="dynamic-table"
1226
+ [ariaLabel]="ariaLabel()"
1227
+ [tngTableSelectedIds]="selectedIds()"
1228
+ (selectionChange)="onSelectionChange($event)"
1229
+ >
1230
+ <thead tngTableHeader>
1231
+ <tr tngTableRow>
1232
+ @for (column of visibleColumns(); track column.id) {
1233
+ <th
1234
+ tngTableHeaderCell
1235
+ [attr.data-testid]="'dynamic-header-' + column.id"
1236
+ [tngTableColumnId]="column.id"
1237
+ scope="col"
1238
+ >
1239
+ {{ column.label }}
1240
+ </th>
1241
+ }
1242
+ </tr>
1243
+ </thead>
1244
+
1245
+ <tbody tngTableBody>
1246
+ @for (row of rows(); track row.id) {
1247
+ <tr
1248
+ tngTableRow
1249
+ [attr.data-testid]="'dynamic-row-' + row.id"
1250
+ [tngTableRowId]="row.id"
1251
+ >
1252
+ @for (column of visibleColumns(); track column.id) {
1253
+ <td
1254
+ tngTableCell
1255
+ [attr.data-testid]="'dynamic-cell-' + row.id + '-' + column.id"
1256
+ [tngTableColumnId]="column.id"
1257
+ >
1258
+ {{ renderCell(row, column.id) }}
1259
+ </td>
1260
+ }
1261
+ </tr>
1262
+ }
1263
+ </tbody>
1264
+ </table>
1265
+ `,
1266
+ }]
1267
+ }] });
1268
+ export class TableRenderingHarnessComponent {
1269
+ footerValue = signal(2, ...(ngDevMode ? [{ debugName: "footerValue" }] : []));
1270
+ localizedFooterValue = signal(9876.5, ...(ngDevMode ? [{ debugName: "localizedFooterValue" }] : []));
1271
+ localizedNumberValue = signal(12345.67, ...(ngDevMode ? [{ debugName: "localizedNumberValue" }] : []));
1272
+ rows = signal([
1273
+ {
1274
+ active: true,
1275
+ id: 'alpha',
1276
+ label: 'Alpha',
1277
+ markup: '<strong>Safe</strong>',
1278
+ status: 'Active',
1279
+ total: 42,
1280
+ updatedAt: new Date('2026-04-24T00:00:00.000Z'),
1281
+ },
1282
+ {
1283
+ active: false,
1284
+ id: 'beta',
1285
+ label: 'Beta',
1286
+ markup: '<em>Draft</em>',
1287
+ status: 'Draft',
1288
+ total: 18,
1289
+ updatedAt: new Date('2026-04-23T00:00:00.000Z'),
1290
+ },
1291
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
1292
+ localizedDateFormatter = createTngTableIntlDateFormatter('en-GB', {
1293
+ day: '2-digit',
1294
+ month: '2-digit',
1295
+ timeZone: 'UTC',
1296
+ year: 'numeric',
1297
+ });
1298
+ localizedNumberFormatter = createTngTableIntlNumberFormatter('de-DE', {
1299
+ maximumFractionDigits: 2,
1300
+ minimumFractionDigits: 2,
1301
+ });
1302
+ statusFormatter = (value) => `formatted:${String(value).toUpperCase()}`;
1303
+ throwingFormatter = () => {
1304
+ throw new Error('Formatter failure');
1305
+ };
1306
+ errorCellOutlet;
1307
+ footerOutlet;
1308
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableRenderingHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1309
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: TableRenderingHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "errorCellOutlet", first: true, predicate: ["errorCellOutlet"], descendants: true }, { propertyName: "footerOutlet", first: true, predicate: ["footerOutlet"], descendants: true }], ngImport: i0, template: `
1310
+ <ng-template
1311
+ tngTableCellTpl
1312
+ #cellTemplate="tngTableCellTpl"
1313
+ let-columnId="columnId"
1314
+ let-row="row"
1315
+ let-value
1316
+ >
1317
+ <span data-testid="custom-cell-content">{{ row.id }}::{{ columnId }}::{{ value }}</span>
1318
+ </ng-template>
1319
+
1320
+ <ng-template
1321
+ tngTableHeaderTpl
1322
+ #headerTemplate="tngTableHeaderTpl"
1323
+ let-columnId="columnId"
1324
+ let-label
1325
+ >
1326
+ <span data-testid="custom-header-content">{{ columnId }}::{{ label }}</span>
1327
+ </ng-template>
1328
+
1329
+ <ng-template
1330
+ tngTableFooterTpl
1331
+ #footerTemplate="tngTableFooterTpl"
1332
+ let-columnId="columnId"
1333
+ let-items="items"
1334
+ let-value
1335
+ >
1336
+ <span data-testid="custom-footer-content">{{ columnId }}::{{ items.length }}::{{ value }}</span>
1337
+ </ng-template>
1338
+
1339
+ <ng-template tngTableCellTpl #htmlTemplate="tngTableCellTpl" let-value>
1340
+ <span data-testid="custom-html-content" [innerHTML]="value"></span>
1341
+ </ng-template>
1342
+
1343
+ <table tngTable data-testid="rendering-table">
1344
+ <thead tngTableHeader>
1345
+ <tr tngTableRow>
1346
+ <th tngTableHeaderCell data-testid="default-header">
1347
+ <tng-table-header-outlet
1348
+ [columnId]="'label'"
1349
+ [label]="'Name'"
1350
+ ></tng-table-header-outlet>
1351
+ </th>
1352
+ <th tngTableHeaderCell data-testid="custom-header">
1353
+ <tng-table-header-outlet
1354
+ [columnId]="'status'"
1355
+ [label]="'Status'"
1356
+ [template]="headerTemplate"
1357
+ ></tng-table-header-outlet>
1358
+ </th>
1359
+ </tr>
1360
+ </thead>
1361
+
1362
+ <tbody tngTableBody>
1363
+ <tr tngTableRow [tngTableRowId]="rows()[0].id">
1364
+ <td tngTableCell data-testid="default-string-cell">
1365
+ <tng-table-cell-outlet
1366
+ [columnId]="'label'"
1367
+ [row]="rows()[0]"
1368
+ [rowId]="rows()[0].id"
1369
+ [value]="rows()[0].label"
1370
+ ></tng-table-cell-outlet>
1371
+ </td>
1372
+ <td tngTableCell data-testid="default-number-cell">
1373
+ <tng-table-cell-outlet
1374
+ [columnId]="'total'"
1375
+ [row]="rows()[0]"
1376
+ [rowId]="rows()[0].id"
1377
+ [value]="rows()[0].total"
1378
+ ></tng-table-cell-outlet>
1379
+ </td>
1380
+ <td tngTableCell data-testid="default-boolean-cell">
1381
+ <tng-table-cell-outlet
1382
+ [columnId]="'active'"
1383
+ [row]="rows()[0]"
1384
+ [rowId]="rows()[0].id"
1385
+ [value]="rows()[0].active"
1386
+ ></tng-table-cell-outlet>
1387
+ </td>
1388
+ <td tngTableCell data-testid="custom-cell">
1389
+ <tng-table-cell-outlet
1390
+ [columnId]="'status'"
1391
+ [row]="rows()[0]"
1392
+ [rowId]="rows()[0].id"
1393
+ [template]="cellTemplate"
1394
+ [value]="rows()[0].status"
1395
+ ></tng-table-cell-outlet>
1396
+ </td>
1397
+ <td tngTableCell data-testid="formatted-cell">
1398
+ <tng-table-cell-outlet
1399
+ [columnId]="'status'"
1400
+ [formatter]="statusFormatter"
1401
+ [row]="rows()[0]"
1402
+ [rowId]="rows()[0].id"
1403
+ [value]="rows()[0].status"
1404
+ ></tng-table-cell-outlet>
1405
+ </td>
1406
+ <td tngTableCell data-testid="formatter-error-cell">
1407
+ <tng-table-cell-outlet
1408
+ #errorCellOutlet="tngTableCellOutlet"
1409
+ [columnId]="'status'"
1410
+ [formatter]="throwingFormatter"
1411
+ [row]="rows()[0]"
1412
+ [rowId]="rows()[0].id"
1413
+ [value]="rows()[0].status"
1414
+ ></tng-table-cell-outlet>
1415
+ </td>
1416
+ <td tngTableCell data-testid="html-escape-cell">
1417
+ <tng-table-cell-outlet
1418
+ [columnId]="'markup'"
1419
+ [row]="rows()[0]"
1420
+ [rowId]="rows()[0].id"
1421
+ [value]="rows()[0].markup"
1422
+ ></tng-table-cell-outlet>
1423
+ </td>
1424
+ <td tngTableCell data-testid="html-optin-cell">
1425
+ <tng-table-cell-outlet
1426
+ [columnId]="'markup'"
1427
+ [row]="rows()[0]"
1428
+ [rowId]="rows()[0].id"
1429
+ [template]="htmlTemplate"
1430
+ [value]="rows()[0].markup"
1431
+ ></tng-table-cell-outlet>
1432
+ </td>
1433
+ <td tngTableCell data-testid="localized-number-cell">
1434
+ <tng-table-cell-outlet
1435
+ [columnId]="'localizedTotal'"
1436
+ [formatter]="localizedNumberFormatter"
1437
+ [row]="rows()[0]"
1438
+ [rowId]="rows()[0].id"
1439
+ [value]="localizedNumberValue()"
1440
+ ></tng-table-cell-outlet>
1441
+ </td>
1442
+ <td tngTableCell data-testid="localized-date-cell">
1443
+ <tng-table-cell-outlet
1444
+ [columnId]="'updatedAt'"
1445
+ [formatter]="localizedDateFormatter"
1446
+ [row]="rows()[0]"
1447
+ [rowId]="rows()[0].id"
1448
+ [value]="rows()[0].updatedAt"
1449
+ ></tng-table-cell-outlet>
1450
+ </td>
1451
+ </tr>
1452
+ </tbody>
1453
+
1454
+ <tfoot tngTableFooter>
1455
+ <tr tngTableRow>
1456
+ <td tngTableCell data-testid="default-footer-cell">
1457
+ <tng-table-footer-outlet
1458
+ [columnId]="'total'"
1459
+ [items]="rows()"
1460
+ [value]="footerValue()"
1461
+ ></tng-table-footer-outlet>
1462
+ </td>
1463
+ <td tngTableCell data-testid="custom-footer-cell">
1464
+ <tng-table-footer-outlet
1465
+ #footerOutlet="tngTableFooterOutlet"
1466
+ [columnId]="'summary'"
1467
+ [items]="rows()"
1468
+ [template]="footerTemplate"
1469
+ [value]="footerValue()"
1470
+ ></tng-table-footer-outlet>
1471
+ </td>
1472
+ <td tngTableCell data-testid="localized-footer-cell">
1473
+ <tng-table-footer-outlet
1474
+ [columnId]="'localizedTotal'"
1475
+ [formatter]="localizedNumberFormatter"
1476
+ [items]="rows()"
1477
+ [value]="localizedFooterValue()"
1478
+ ></tng-table-footer-outlet>
1479
+ </td>
1480
+ </tr>
1481
+ </tfoot>
1482
+ </table>
1483
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableFooter, selector: "tfoot[tngTableFooter]", inputs: ["tngTableFooterSticky", "tngTableFooterStickyOffset"], exportAs: ["tngTableFooter"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "component", type: TngTableCellOutlet, selector: "tng-table-cell-outlet", inputs: ["columnId", "formatter", "row", "rowId", "template", "value"], exportAs: ["tngTableCellOutlet"] }, { kind: "directive", type: TngTableCellTpl, selector: "ng-template[tngTableCellTpl]", exportAs: ["tngTableCellTpl"] }, { kind: "component", type: TngTableHeaderOutlet, selector: "tng-table-header-outlet", inputs: ["columnId", "label", "template"], exportAs: ["tngTableHeaderOutlet"] }, { kind: "directive", type: TngTableHeaderTpl, selector: "ng-template[tngTableHeaderTpl]", exportAs: ["tngTableHeaderTpl"] }, { kind: "component", type: TngTableFooterOutlet, selector: "tng-table-footer-outlet", inputs: ["columnId", "formatter", "items", "template", "value"], exportAs: ["tngTableFooterOutlet"] }, { kind: "directive", type: TngTableFooterTpl, selector: "ng-template[tngTableFooterTpl]", exportAs: ["tngTableFooterTpl"] }] });
1484
+ }
1485
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableRenderingHarnessComponent, decorators: [{
1486
+ type: Component,
1487
+ args: [{
1488
+ imports: [
1489
+ TngTable,
1490
+ TngTableHeader,
1491
+ TngTableBody,
1492
+ TngTableFooter,
1493
+ TngTableRow,
1494
+ TngTableHeaderCell,
1495
+ TngTableCell,
1496
+ TngTableCellOutlet,
1497
+ TngTableCellTpl,
1498
+ TngTableHeaderOutlet,
1499
+ TngTableHeaderTpl,
1500
+ TngTableFooterOutlet,
1501
+ TngTableFooterTpl,
1502
+ ],
1503
+ template: `
1504
+ <ng-template
1505
+ tngTableCellTpl
1506
+ #cellTemplate="tngTableCellTpl"
1507
+ let-columnId="columnId"
1508
+ let-row="row"
1509
+ let-value
1510
+ >
1511
+ <span data-testid="custom-cell-content">{{ row.id }}::{{ columnId }}::{{ value }}</span>
1512
+ </ng-template>
1513
+
1514
+ <ng-template
1515
+ tngTableHeaderTpl
1516
+ #headerTemplate="tngTableHeaderTpl"
1517
+ let-columnId="columnId"
1518
+ let-label
1519
+ >
1520
+ <span data-testid="custom-header-content">{{ columnId }}::{{ label }}</span>
1521
+ </ng-template>
1522
+
1523
+ <ng-template
1524
+ tngTableFooterTpl
1525
+ #footerTemplate="tngTableFooterTpl"
1526
+ let-columnId="columnId"
1527
+ let-items="items"
1528
+ let-value
1529
+ >
1530
+ <span data-testid="custom-footer-content">{{ columnId }}::{{ items.length }}::{{ value }}</span>
1531
+ </ng-template>
1532
+
1533
+ <ng-template tngTableCellTpl #htmlTemplate="tngTableCellTpl" let-value>
1534
+ <span data-testid="custom-html-content" [innerHTML]="value"></span>
1535
+ </ng-template>
1536
+
1537
+ <table tngTable data-testid="rendering-table">
1538
+ <thead tngTableHeader>
1539
+ <tr tngTableRow>
1540
+ <th tngTableHeaderCell data-testid="default-header">
1541
+ <tng-table-header-outlet
1542
+ [columnId]="'label'"
1543
+ [label]="'Name'"
1544
+ ></tng-table-header-outlet>
1545
+ </th>
1546
+ <th tngTableHeaderCell data-testid="custom-header">
1547
+ <tng-table-header-outlet
1548
+ [columnId]="'status'"
1549
+ [label]="'Status'"
1550
+ [template]="headerTemplate"
1551
+ ></tng-table-header-outlet>
1552
+ </th>
1553
+ </tr>
1554
+ </thead>
1555
+
1556
+ <tbody tngTableBody>
1557
+ <tr tngTableRow [tngTableRowId]="rows()[0].id">
1558
+ <td tngTableCell data-testid="default-string-cell">
1559
+ <tng-table-cell-outlet
1560
+ [columnId]="'label'"
1561
+ [row]="rows()[0]"
1562
+ [rowId]="rows()[0].id"
1563
+ [value]="rows()[0].label"
1564
+ ></tng-table-cell-outlet>
1565
+ </td>
1566
+ <td tngTableCell data-testid="default-number-cell">
1567
+ <tng-table-cell-outlet
1568
+ [columnId]="'total'"
1569
+ [row]="rows()[0]"
1570
+ [rowId]="rows()[0].id"
1571
+ [value]="rows()[0].total"
1572
+ ></tng-table-cell-outlet>
1573
+ </td>
1574
+ <td tngTableCell data-testid="default-boolean-cell">
1575
+ <tng-table-cell-outlet
1576
+ [columnId]="'active'"
1577
+ [row]="rows()[0]"
1578
+ [rowId]="rows()[0].id"
1579
+ [value]="rows()[0].active"
1580
+ ></tng-table-cell-outlet>
1581
+ </td>
1582
+ <td tngTableCell data-testid="custom-cell">
1583
+ <tng-table-cell-outlet
1584
+ [columnId]="'status'"
1585
+ [row]="rows()[0]"
1586
+ [rowId]="rows()[0].id"
1587
+ [template]="cellTemplate"
1588
+ [value]="rows()[0].status"
1589
+ ></tng-table-cell-outlet>
1590
+ </td>
1591
+ <td tngTableCell data-testid="formatted-cell">
1592
+ <tng-table-cell-outlet
1593
+ [columnId]="'status'"
1594
+ [formatter]="statusFormatter"
1595
+ [row]="rows()[0]"
1596
+ [rowId]="rows()[0].id"
1597
+ [value]="rows()[0].status"
1598
+ ></tng-table-cell-outlet>
1599
+ </td>
1600
+ <td tngTableCell data-testid="formatter-error-cell">
1601
+ <tng-table-cell-outlet
1602
+ #errorCellOutlet="tngTableCellOutlet"
1603
+ [columnId]="'status'"
1604
+ [formatter]="throwingFormatter"
1605
+ [row]="rows()[0]"
1606
+ [rowId]="rows()[0].id"
1607
+ [value]="rows()[0].status"
1608
+ ></tng-table-cell-outlet>
1609
+ </td>
1610
+ <td tngTableCell data-testid="html-escape-cell">
1611
+ <tng-table-cell-outlet
1612
+ [columnId]="'markup'"
1613
+ [row]="rows()[0]"
1614
+ [rowId]="rows()[0].id"
1615
+ [value]="rows()[0].markup"
1616
+ ></tng-table-cell-outlet>
1617
+ </td>
1618
+ <td tngTableCell data-testid="html-optin-cell">
1619
+ <tng-table-cell-outlet
1620
+ [columnId]="'markup'"
1621
+ [row]="rows()[0]"
1622
+ [rowId]="rows()[0].id"
1623
+ [template]="htmlTemplate"
1624
+ [value]="rows()[0].markup"
1625
+ ></tng-table-cell-outlet>
1626
+ </td>
1627
+ <td tngTableCell data-testid="localized-number-cell">
1628
+ <tng-table-cell-outlet
1629
+ [columnId]="'localizedTotal'"
1630
+ [formatter]="localizedNumberFormatter"
1631
+ [row]="rows()[0]"
1632
+ [rowId]="rows()[0].id"
1633
+ [value]="localizedNumberValue()"
1634
+ ></tng-table-cell-outlet>
1635
+ </td>
1636
+ <td tngTableCell data-testid="localized-date-cell">
1637
+ <tng-table-cell-outlet
1638
+ [columnId]="'updatedAt'"
1639
+ [formatter]="localizedDateFormatter"
1640
+ [row]="rows()[0]"
1641
+ [rowId]="rows()[0].id"
1642
+ [value]="rows()[0].updatedAt"
1643
+ ></tng-table-cell-outlet>
1644
+ </td>
1645
+ </tr>
1646
+ </tbody>
1647
+
1648
+ <tfoot tngTableFooter>
1649
+ <tr tngTableRow>
1650
+ <td tngTableCell data-testid="default-footer-cell">
1651
+ <tng-table-footer-outlet
1652
+ [columnId]="'total'"
1653
+ [items]="rows()"
1654
+ [value]="footerValue()"
1655
+ ></tng-table-footer-outlet>
1656
+ </td>
1657
+ <td tngTableCell data-testid="custom-footer-cell">
1658
+ <tng-table-footer-outlet
1659
+ #footerOutlet="tngTableFooterOutlet"
1660
+ [columnId]="'summary'"
1661
+ [items]="rows()"
1662
+ [template]="footerTemplate"
1663
+ [value]="footerValue()"
1664
+ ></tng-table-footer-outlet>
1665
+ </td>
1666
+ <td tngTableCell data-testid="localized-footer-cell">
1667
+ <tng-table-footer-outlet
1668
+ [columnId]="'localizedTotal'"
1669
+ [formatter]="localizedNumberFormatter"
1670
+ [items]="rows()"
1671
+ [value]="localizedFooterValue()"
1672
+ ></tng-table-footer-outlet>
1673
+ </td>
1674
+ </tr>
1675
+ </tfoot>
1676
+ </table>
1677
+ `,
1678
+ }]
1679
+ }], propDecorators: { errorCellOutlet: [{
1680
+ type: ViewChild,
1681
+ args: ['errorCellOutlet']
1682
+ }], footerOutlet: [{
1683
+ type: ViewChild,
1684
+ args: ['footerOutlet']
1685
+ }] } });
1686
+ export class TableLayoutHarnessComponent {
1687
+ dir = signal('ltr', ...(ngDevMode ? [{ debugName: "dir" }] : []));
1688
+ footerStickyOffset = signal('8px', ...(ngDevMode ? [{ debugName: "footerStickyOffset" }] : []));
1689
+ headerStickyOffset = signal('12px', ...(ngDevMode ? [{ debugName: "headerStickyOffset" }] : []));
1690
+ labelStickyOffset = signal(null, ...(ngDevMode ? [{ debugName: "labelStickyOffset" }] : []));
1691
+ labelStickySide = signal(null, ...(ngDevMode ? [{ debugName: "labelStickySide" }] : []));
1692
+ layout = signal('auto', ...(ngDevMode ? [{ debugName: "layout" }] : []));
1693
+ scrollAxis = signal('x', ...(ngDevMode ? [{ debugName: "scrollAxis" }] : []));
1694
+ statusStickyOffset = signal(null, ...(ngDevMode ? [{ debugName: "statusStickyOffset" }] : []));
1695
+ statusStickySide = signal(null, ...(ngDevMode ? [{ debugName: "statusStickySide" }] : []));
1696
+ stickyFooter = signal(false, ...(ngDevMode ? [{ debugName: "stickyFooter" }] : []));
1697
+ stickyHeader = signal(false, ...(ngDevMode ? [{ debugName: "stickyHeader" }] : []));
1698
+ truncate = signal(false, ...(ngDevMode ? [{ debugName: "truncate" }] : []));
1699
+ valueStickyOffset = signal(null, ...(ngDevMode ? [{ debugName: "valueStickyOffset" }] : []));
1700
+ valueStickySide = signal(null, ...(ngDevMode ? [{ debugName: "valueStickySide" }] : []));
1701
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableLayoutHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1702
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: TableLayoutHarnessComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
1703
+ <div
1704
+ tngTableScrollContainer
1705
+ data-testid="layout-scroll"
1706
+ [dir]="dir()"
1707
+ [tngTableScrollAxis]="scrollAxis()"
1708
+ >
1709
+ <table
1710
+ tngTable
1711
+ data-testid="layout-table"
1712
+ [dir]="dir()"
1713
+ [tngTableLayout]="layout()"
1714
+ >
1715
+ <thead
1716
+ tngTableHeader
1717
+ data-testid="layout-header"
1718
+ [tngTableHeaderSticky]="stickyHeader()"
1719
+ [tngTableHeaderStickyOffset]="headerStickyOffset()"
1720
+ >
1721
+ <tr tngTableRow>
1722
+ <th
1723
+ tngTableHeaderCell
1724
+ data-testid="layout-header-label"
1725
+ [tngTableColumnId]="'label'"
1726
+ [tngTableStickyColumn]="labelStickySide()"
1727
+ [tngTableStickyOffset]="labelStickyOffset()"
1728
+ [tngTableTruncate]="truncate()"
1729
+ >
1730
+ Project name
1731
+ </th>
1732
+ <th
1733
+ tngTableHeaderCell
1734
+ data-testid="layout-header-status"
1735
+ [tngTableColumnId]="'status'"
1736
+ [tngTableStickyColumn]="statusStickySide()"
1737
+ [tngTableStickyOffset]="statusStickyOffset()"
1738
+ >
1739
+ Status
1740
+ </th>
1741
+ <th
1742
+ tngTableHeaderCell
1743
+ data-testid="layout-header-value"
1744
+ [tngTableColumnId]="'value'"
1745
+ [tngTableStickyColumn]="valueStickySide()"
1746
+ [tngTableStickyOffset]="valueStickyOffset()"
1747
+ >
1748
+ Value
1749
+ </th>
1750
+ </tr>
1751
+ </thead>
1752
+
1753
+ <tbody tngTableBody>
1754
+ <tr tngTableRow [tngTableRowId]="'alpha'">
1755
+ <td
1756
+ tngTableCell
1757
+ data-testid="layout-cell-label"
1758
+ [tngTableColumnId]="'label'"
1759
+ [tngTableStickyColumn]="labelStickySide()"
1760
+ [tngTableStickyOffset]="labelStickyOffset()"
1761
+ [tngTableTruncate]="truncate()"
1762
+ >
1763
+ A very long label that should truncate in fixed layout mode
1764
+ </td>
1765
+ <td
1766
+ tngTableCell
1767
+ data-testid="layout-cell-status"
1768
+ [tngTableColumnId]="'status'"
1769
+ [tngTableStickyColumn]="statusStickySide()"
1770
+ [tngTableStickyOffset]="statusStickyOffset()"
1771
+ >
1772
+ Ready
1773
+ </td>
1774
+ <td
1775
+ tngTableCell
1776
+ data-testid="layout-cell-value"
1777
+ [tngTableColumnId]="'value'"
1778
+ [tngTableStickyColumn]="valueStickySide()"
1779
+ [tngTableStickyOffset]="valueStickyOffset()"
1780
+ >
1781
+ 42
1782
+ </td>
1783
+ </tr>
1784
+ </tbody>
1785
+
1786
+ <tfoot
1787
+ tngTableFooter
1788
+ data-testid="layout-footer"
1789
+ [tngTableFooterSticky]="stickyFooter()"
1790
+ [tngTableFooterStickyOffset]="footerStickyOffset()"
1791
+ >
1792
+ <tr tngTableRow>
1793
+ <td
1794
+ tngTableCell
1795
+ data-testid="layout-footer-label"
1796
+ [tngTableColumnId]="'label'"
1797
+ [tngTableStickyColumn]="labelStickySide()"
1798
+ [tngTableStickyOffset]="labelStickyOffset()"
1799
+ >
1800
+ Totals
1801
+ </td>
1802
+ <td
1803
+ tngTableCell
1804
+ data-testid="layout-footer-status"
1805
+ [tngTableColumnId]="'status'"
1806
+ [tngTableStickyColumn]="statusStickySide()"
1807
+ [tngTableStickyOffset]="statusStickyOffset()"
1808
+ >
1809
+ Complete
1810
+ </td>
1811
+ <td
1812
+ tngTableCell
1813
+ data-testid="layout-footer-value"
1814
+ [tngTableColumnId]="'value'"
1815
+ [tngTableStickyColumn]="valueStickySide()"
1816
+ [tngTableStickyOffset]="valueStickyOffset()"
1817
+ >
1818
+ 42
1819
+ </td>
1820
+ </tr>
1821
+ </tfoot>
1822
+ </table>
1823
+ </div>
1824
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableScrollContainer, selector: "[tngTableScrollContainer]", inputs: ["tngTableScrollAxis", "dir"], exportAs: ["tngTableScrollContainer"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableFooter, selector: "tfoot[tngTableFooter]", inputs: ["tngTableFooterSticky", "tngTableFooterStickyOffset"], exportAs: ["tngTableFooter"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }] });
1825
+ }
1826
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableLayoutHarnessComponent, decorators: [{
1827
+ type: Component,
1828
+ args: [{
1829
+ imports: [
1830
+ TngTable,
1831
+ TngTableScrollContainer,
1832
+ TngTableHeader,
1833
+ TngTableBody,
1834
+ TngTableFooter,
1835
+ TngTableRow,
1836
+ TngTableHeaderCell,
1837
+ TngTableCell,
1838
+ ],
1839
+ template: `
1840
+ <div
1841
+ tngTableScrollContainer
1842
+ data-testid="layout-scroll"
1843
+ [dir]="dir()"
1844
+ [tngTableScrollAxis]="scrollAxis()"
1845
+ >
1846
+ <table
1847
+ tngTable
1848
+ data-testid="layout-table"
1849
+ [dir]="dir()"
1850
+ [tngTableLayout]="layout()"
1851
+ >
1852
+ <thead
1853
+ tngTableHeader
1854
+ data-testid="layout-header"
1855
+ [tngTableHeaderSticky]="stickyHeader()"
1856
+ [tngTableHeaderStickyOffset]="headerStickyOffset()"
1857
+ >
1858
+ <tr tngTableRow>
1859
+ <th
1860
+ tngTableHeaderCell
1861
+ data-testid="layout-header-label"
1862
+ [tngTableColumnId]="'label'"
1863
+ [tngTableStickyColumn]="labelStickySide()"
1864
+ [tngTableStickyOffset]="labelStickyOffset()"
1865
+ [tngTableTruncate]="truncate()"
1866
+ >
1867
+ Project name
1868
+ </th>
1869
+ <th
1870
+ tngTableHeaderCell
1871
+ data-testid="layout-header-status"
1872
+ [tngTableColumnId]="'status'"
1873
+ [tngTableStickyColumn]="statusStickySide()"
1874
+ [tngTableStickyOffset]="statusStickyOffset()"
1875
+ >
1876
+ Status
1877
+ </th>
1878
+ <th
1879
+ tngTableHeaderCell
1880
+ data-testid="layout-header-value"
1881
+ [tngTableColumnId]="'value'"
1882
+ [tngTableStickyColumn]="valueStickySide()"
1883
+ [tngTableStickyOffset]="valueStickyOffset()"
1884
+ >
1885
+ Value
1886
+ </th>
1887
+ </tr>
1888
+ </thead>
1889
+
1890
+ <tbody tngTableBody>
1891
+ <tr tngTableRow [tngTableRowId]="'alpha'">
1892
+ <td
1893
+ tngTableCell
1894
+ data-testid="layout-cell-label"
1895
+ [tngTableColumnId]="'label'"
1896
+ [tngTableStickyColumn]="labelStickySide()"
1897
+ [tngTableStickyOffset]="labelStickyOffset()"
1898
+ [tngTableTruncate]="truncate()"
1899
+ >
1900
+ A very long label that should truncate in fixed layout mode
1901
+ </td>
1902
+ <td
1903
+ tngTableCell
1904
+ data-testid="layout-cell-status"
1905
+ [tngTableColumnId]="'status'"
1906
+ [tngTableStickyColumn]="statusStickySide()"
1907
+ [tngTableStickyOffset]="statusStickyOffset()"
1908
+ >
1909
+ Ready
1910
+ </td>
1911
+ <td
1912
+ tngTableCell
1913
+ data-testid="layout-cell-value"
1914
+ [tngTableColumnId]="'value'"
1915
+ [tngTableStickyColumn]="valueStickySide()"
1916
+ [tngTableStickyOffset]="valueStickyOffset()"
1917
+ >
1918
+ 42
1919
+ </td>
1920
+ </tr>
1921
+ </tbody>
1922
+
1923
+ <tfoot
1924
+ tngTableFooter
1925
+ data-testid="layout-footer"
1926
+ [tngTableFooterSticky]="stickyFooter()"
1927
+ [tngTableFooterStickyOffset]="footerStickyOffset()"
1928
+ >
1929
+ <tr tngTableRow>
1930
+ <td
1931
+ tngTableCell
1932
+ data-testid="layout-footer-label"
1933
+ [tngTableColumnId]="'label'"
1934
+ [tngTableStickyColumn]="labelStickySide()"
1935
+ [tngTableStickyOffset]="labelStickyOffset()"
1936
+ >
1937
+ Totals
1938
+ </td>
1939
+ <td
1940
+ tngTableCell
1941
+ data-testid="layout-footer-status"
1942
+ [tngTableColumnId]="'status'"
1943
+ [tngTableStickyColumn]="statusStickySide()"
1944
+ [tngTableStickyOffset]="statusStickyOffset()"
1945
+ >
1946
+ Complete
1947
+ </td>
1948
+ <td
1949
+ tngTableCell
1950
+ data-testid="layout-footer-value"
1951
+ [tngTableColumnId]="'value'"
1952
+ [tngTableStickyColumn]="valueStickySide()"
1953
+ [tngTableStickyOffset]="valueStickyOffset()"
1954
+ >
1955
+ 42
1956
+ </td>
1957
+ </tr>
1958
+ </tfoot>
1959
+ </table>
1960
+ </div>
1961
+ `,
1962
+ }]
1963
+ }] });
1964
+ export class TableSizingHarnessComponent {
1965
+ dir = signal('ltr', ...(ngDevMode ? [{ debugName: "dir" }] : []));
1966
+ widthEvents = [];
1967
+ widths = signal(undefined, ...(ngDevMode ? [{ debugName: "widths" }] : []));
1968
+ onWidthsChange(nextWidths) {
1969
+ this.widths.set({ ...nextWidths });
1970
+ this.widthEvents.push(nextWidths);
1971
+ }
1972
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSizingHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1973
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: TableSizingHarnessComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: `
1974
+ <table
1975
+ tngTable
1976
+ tngTableColumnSizing
1977
+ data-testid="sizing-table"
1978
+ [dir]="dir()"
1979
+ [tngTableColumnWidths]="widths()"
1980
+ (columnWidthsChange)="onWidthsChange($event)"
1981
+ >
1982
+ <thead tngTableHeader>
1983
+ <tr tngTableRow>
1984
+ <th
1985
+ tngTableHeaderCell
1986
+ tngTableColumn
1987
+ data-testid="sizing-header-label"
1988
+ [tngTableColumn]="'label'"
1989
+ [tngTableColumnWidth]="'240px'"
1990
+ >
1991
+ Label
1992
+ <span [tngTableColumnResizer]="'label'" data-testid="label-resizer"></span>
1993
+ </th>
1994
+ <th
1995
+ tngTableHeaderCell
1996
+ tngTableColumn
1997
+ data-testid="sizing-header-status"
1998
+ [tngTableColumn]="'status'"
1999
+ [tngTableColumnMaxWidth]="'220px'"
2000
+ [tngTableColumnMinWidth]="'120px'"
2001
+ [tngTableColumnWidth]="'140px'"
2002
+ >
2003
+ Status
2004
+ <span [tngTableColumnResizer]="'status'" data-testid="status-resizer"></span>
2005
+ </th>
2006
+ <th
2007
+ tngTableHeaderCell
2008
+ tngTableColumn
2009
+ data-testid="sizing-header-value"
2010
+ [tngTableColumn]="'value'"
2011
+ [tngTableColumnWidth]="'96px'"
2012
+ >
2013
+ Value
2014
+ <span [tngTableColumnResizer]="'value'" data-testid="value-resizer"></span>
2015
+ </th>
2016
+ </tr>
2017
+ </thead>
2018
+
2019
+ <tbody tngTableBody>
2020
+ <tr tngTableRow [tngTableRowId]="'alpha'">
2021
+ <td
2022
+ tngTableCell
2023
+ tngTableColumn
2024
+ data-testid="sizing-cell-label"
2025
+ [tngTableColumn]="'label'"
2026
+ [tngTableColumnWidth]="'240px'"
2027
+ >
2028
+ Alpha
2029
+ </td>
2030
+ <td
2031
+ tngTableCell
2032
+ tngTableColumn
2033
+ data-testid="sizing-cell-status"
2034
+ [tngTableColumn]="'status'"
2035
+ [tngTableColumnMaxWidth]="'220px'"
2036
+ [tngTableColumnMinWidth]="'120px'"
2037
+ [tngTableColumnWidth]="'140px'"
2038
+ >
2039
+ Ready
2040
+ </td>
2041
+ <td
2042
+ tngTableCell
2043
+ tngTableColumn
2044
+ data-testid="sizing-cell-value"
2045
+ [tngTableColumn]="'value'"
2046
+ [tngTableColumnWidth]="'96px'"
2047
+ >
2048
+ 42
2049
+ </td>
2050
+ </tr>
2051
+ </tbody>
2052
+ </table>
2053
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableColumnSizing, selector: "table[tngTable][tngTableColumnSizing]", inputs: ["tngTableColumnWidths"], outputs: ["columnWidthsChange"], exportAs: ["tngTableColumnSizing"] }, { kind: "directive", type: TngTableColumn, selector: "th[tngTableColumn],td[tngTableColumn]", inputs: ["tngTableColumn", "tngTableColumnWidth", "tngTableColumnMinWidth", "tngTableColumnMaxWidth"], exportAs: ["tngTableColumn"] }, { kind: "directive", type: TngTableColumnResizer, selector: "[tngTableColumnResizer]", inputs: ["tngTableColumnResizer", "tngTableColumnResizerDisabled"], exportAs: ["tngTableColumnResizer"] }] });
2054
+ }
2055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableSizingHarnessComponent, decorators: [{
2056
+ type: Component,
2057
+ args: [{
2058
+ imports: [
2059
+ TngTable,
2060
+ TngTableHeader,
2061
+ TngTableBody,
2062
+ TngTableRow,
2063
+ TngTableHeaderCell,
2064
+ TngTableCell,
2065
+ TngTableColumnSizing,
2066
+ TngTableColumn,
2067
+ TngTableColumnResizer,
2068
+ ],
2069
+ template: `
2070
+ <table
2071
+ tngTable
2072
+ tngTableColumnSizing
2073
+ data-testid="sizing-table"
2074
+ [dir]="dir()"
2075
+ [tngTableColumnWidths]="widths()"
2076
+ (columnWidthsChange)="onWidthsChange($event)"
2077
+ >
2078
+ <thead tngTableHeader>
2079
+ <tr tngTableRow>
2080
+ <th
2081
+ tngTableHeaderCell
2082
+ tngTableColumn
2083
+ data-testid="sizing-header-label"
2084
+ [tngTableColumn]="'label'"
2085
+ [tngTableColumnWidth]="'240px'"
2086
+ >
2087
+ Label
2088
+ <span [tngTableColumnResizer]="'label'" data-testid="label-resizer"></span>
2089
+ </th>
2090
+ <th
2091
+ tngTableHeaderCell
2092
+ tngTableColumn
2093
+ data-testid="sizing-header-status"
2094
+ [tngTableColumn]="'status'"
2095
+ [tngTableColumnMaxWidth]="'220px'"
2096
+ [tngTableColumnMinWidth]="'120px'"
2097
+ [tngTableColumnWidth]="'140px'"
2098
+ >
2099
+ Status
2100
+ <span [tngTableColumnResizer]="'status'" data-testid="status-resizer"></span>
2101
+ </th>
2102
+ <th
2103
+ tngTableHeaderCell
2104
+ tngTableColumn
2105
+ data-testid="sizing-header-value"
2106
+ [tngTableColumn]="'value'"
2107
+ [tngTableColumnWidth]="'96px'"
2108
+ >
2109
+ Value
2110
+ <span [tngTableColumnResizer]="'value'" data-testid="value-resizer"></span>
2111
+ </th>
2112
+ </tr>
2113
+ </thead>
2114
+
2115
+ <tbody tngTableBody>
2116
+ <tr tngTableRow [tngTableRowId]="'alpha'">
2117
+ <td
2118
+ tngTableCell
2119
+ tngTableColumn
2120
+ data-testid="sizing-cell-label"
2121
+ [tngTableColumn]="'label'"
2122
+ [tngTableColumnWidth]="'240px'"
2123
+ >
2124
+ Alpha
2125
+ </td>
2126
+ <td
2127
+ tngTableCell
2128
+ tngTableColumn
2129
+ data-testid="sizing-cell-status"
2130
+ [tngTableColumn]="'status'"
2131
+ [tngTableColumnMaxWidth]="'220px'"
2132
+ [tngTableColumnMinWidth]="'120px'"
2133
+ [tngTableColumnWidth]="'140px'"
2134
+ >
2135
+ Ready
2136
+ </td>
2137
+ <td
2138
+ tngTableCell
2139
+ tngTableColumn
2140
+ data-testid="sizing-cell-value"
2141
+ [tngTableColumn]="'value'"
2142
+ [tngTableColumnWidth]="'96px'"
2143
+ >
2144
+ 42
2145
+ </td>
2146
+ </tr>
2147
+ </tbody>
2148
+ </table>
2149
+ `,
2150
+ }]
2151
+ }] });
2152
+ export class TableVirtualHarnessComponent {
2153
+ overscan = signal(0, ...(ngDevMode ? [{ debugName: "overscan" }] : []));
2154
+ rangeChanges = signal([], ...(ngDevMode ? [{ debugName: "rangeChanges" }] : []));
2155
+ rowHeight = signal(40, ...(ngDevMode ? [{ debugName: "rowHeight" }] : []));
2156
+ rows = signal(Array.from({ length: 20 }, (_, index) => ({
2157
+ id: `row-${index}`,
2158
+ label: `Row ${index}`,
2159
+ status: index % 2 === 0 ? 'Ready' : 'Draft',
2160
+ value: index,
2161
+ })), ...(ngDevMode ? [{ debugName: "rows" }] : []));
2162
+ selectedIds = signal([], ...(ngDevMode ? [{ debugName: "selectedIds" }] : []));
2163
+ stickyHeader = signal(false, ...(ngDevMode ? [{ debugName: "stickyHeader" }] : []));
2164
+ viewportHeight = signal(120, ...(ngDevMode ? [{ debugName: "viewportHeight" }] : []));
2165
+ selectionRef;
2166
+ virtualRef;
2167
+ onSelectionChange(event) {
2168
+ this.selectedIds.set(event.selectedIds);
2169
+ }
2170
+ onRangeChange(event) {
2171
+ this.rangeChanges.set([...this.rangeChanges(), event]);
2172
+ }
2173
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableVirtualHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2174
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableVirtualHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "selectionRef", first: true, predicate: ["selectionRef"], descendants: true }, { propertyName: "virtualRef", first: true, predicate: ["virtualRef"], descendants: true, static: true }], ngImport: i0, template: `
2175
+ <div
2176
+ tngTableScrollContainer
2177
+ tngTableVirtual
2178
+ #virtualRef="tngTableVirtual"
2179
+ data-testid="virtual-scroll"
2180
+ [tngTableScrollAxis]="'both'"
2181
+ [tngTableVirtualItemCount]="rows().length"
2182
+ [tngTableVirtualItemSize]="rowHeight()"
2183
+ [tngTableVirtualOverscan]="overscan()"
2184
+ [tngTableVirtualViewportHeight]="viewportHeight()"
2185
+ (rangeChange)="onRangeChange($event)"
2186
+ >
2187
+ <table
2188
+ tngTable
2189
+ tngTableSelection
2190
+ #selectionRef="tngTableSelection"
2191
+ data-testid="virtual-table"
2192
+ [tngTableSelectedIds]="selectedIds()"
2193
+ (selectionChange)="onSelectionChange($event)"
2194
+ >
2195
+ <thead
2196
+ tngTableHeader
2197
+ data-testid="virtual-header"
2198
+ [tngTableHeaderSticky]="stickyHeader()"
2199
+ >
2200
+ <tr tngTableRow>
2201
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
2202
+ <th tngTableHeaderCell [tngTableColumnId]="'status'">Status</th>
2203
+ <th tngTableHeaderCell [tngTableColumnId]="'value'">Value</th>
2204
+ </tr>
2205
+ </thead>
2206
+
2207
+ <tbody tngTableBody>
2208
+ @if (virtualRef.beforeSize() > 0) {
2209
+ <tr
2210
+ tngTableVirtualSpacer
2211
+ data-testid="virtual-top-spacer"
2212
+ [tngTableVirtualSpacerColspan]="3"
2213
+ [tngTableVirtualSpacerSize]="virtualRef.beforeSize()"
2214
+ ></tr>
2215
+ }
2216
+
2217
+ @for (row of virtualRef.slice(rows()); track row.id) {
2218
+ <tr
2219
+ tngTableRow
2220
+ [attr.data-testid]="'virtual-row-' + row.id"
2221
+ [tngTableRowId]="row.id"
2222
+ >
2223
+ <td tngTableCell [tngTableColumnId]="'label'">{{ row.label }}</td>
2224
+ <td tngTableCell [tngTableColumnId]="'status'">{{ row.status }}</td>
2225
+ <td tngTableCell [tngTableColumnId]="'value'">{{ row.value }}</td>
2226
+ </tr>
2227
+ }
2228
+
2229
+ @if (virtualRef.afterSize() > 0) {
2230
+ <tr
2231
+ tngTableVirtualSpacer
2232
+ data-testid="virtual-bottom-spacer"
2233
+ [tngTableVirtualSpacerColspan]="3"
2234
+ [tngTableVirtualSpacerSize]="virtualRef.afterSize()"
2235
+ ></tr>
2236
+ }
2237
+ </tbody>
2238
+ </table>
2239
+ </div>
2240
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableScrollContainer, selector: "[tngTableScrollContainer]", inputs: ["tngTableScrollAxis", "dir"], exportAs: ["tngTableScrollContainer"] }, { kind: "directive", type: TngTableSelection, selector: "table[tngTable][tngTableSelection]", inputs: ["tngTableSelectionMode", "tngTableSelectedIds"], outputs: ["selectionChange"], exportAs: ["tngTableSelection"] }, { kind: "directive", type: TngTableVirtual, selector: "[tngTableVirtual]", inputs: ["tngTableVirtualItemCount", "tngTableVirtualItemSize", "tngTableVirtualOverscan", "tngTableVirtualViewportHeight"], outputs: ["rangeChange"], exportAs: ["tngTableVirtual"] }, { kind: "component", type: TngTableVirtualSpacer, selector: "tr[tngTableVirtualSpacer]", inputs: ["tngTableVirtualSpacerSize", "tngTableVirtualSpacerColspan"], exportAs: ["tngTableVirtualSpacer"] }] });
2241
+ }
2242
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableVirtualHarnessComponent, decorators: [{
2243
+ type: Component,
2244
+ args: [{
2245
+ imports: [
2246
+ TngTable,
2247
+ TngTableBody,
2248
+ TngTableCell,
2249
+ TngTableHeader,
2250
+ TngTableHeaderCell,
2251
+ TngTableRow,
2252
+ TngTableScrollContainer,
2253
+ TngTableSelection,
2254
+ TngTableVirtual,
2255
+ TngTableVirtualSpacer,
2256
+ ],
2257
+ template: `
2258
+ <div
2259
+ tngTableScrollContainer
2260
+ tngTableVirtual
2261
+ #virtualRef="tngTableVirtual"
2262
+ data-testid="virtual-scroll"
2263
+ [tngTableScrollAxis]="'both'"
2264
+ [tngTableVirtualItemCount]="rows().length"
2265
+ [tngTableVirtualItemSize]="rowHeight()"
2266
+ [tngTableVirtualOverscan]="overscan()"
2267
+ [tngTableVirtualViewportHeight]="viewportHeight()"
2268
+ (rangeChange)="onRangeChange($event)"
2269
+ >
2270
+ <table
2271
+ tngTable
2272
+ tngTableSelection
2273
+ #selectionRef="tngTableSelection"
2274
+ data-testid="virtual-table"
2275
+ [tngTableSelectedIds]="selectedIds()"
2276
+ (selectionChange)="onSelectionChange($event)"
2277
+ >
2278
+ <thead
2279
+ tngTableHeader
2280
+ data-testid="virtual-header"
2281
+ [tngTableHeaderSticky]="stickyHeader()"
2282
+ >
2283
+ <tr tngTableRow>
2284
+ <th tngTableHeaderCell [tngTableColumnId]="'label'">Label</th>
2285
+ <th tngTableHeaderCell [tngTableColumnId]="'status'">Status</th>
2286
+ <th tngTableHeaderCell [tngTableColumnId]="'value'">Value</th>
2287
+ </tr>
2288
+ </thead>
2289
+
2290
+ <tbody tngTableBody>
2291
+ @if (virtualRef.beforeSize() > 0) {
2292
+ <tr
2293
+ tngTableVirtualSpacer
2294
+ data-testid="virtual-top-spacer"
2295
+ [tngTableVirtualSpacerColspan]="3"
2296
+ [tngTableVirtualSpacerSize]="virtualRef.beforeSize()"
2297
+ ></tr>
2298
+ }
2299
+
2300
+ @for (row of virtualRef.slice(rows()); track row.id) {
2301
+ <tr
2302
+ tngTableRow
2303
+ [attr.data-testid]="'virtual-row-' + row.id"
2304
+ [tngTableRowId]="row.id"
2305
+ >
2306
+ <td tngTableCell [tngTableColumnId]="'label'">{{ row.label }}</td>
2307
+ <td tngTableCell [tngTableColumnId]="'status'">{{ row.status }}</td>
2308
+ <td tngTableCell [tngTableColumnId]="'value'">{{ row.value }}</td>
2309
+ </tr>
2310
+ }
2311
+
2312
+ @if (virtualRef.afterSize() > 0) {
2313
+ <tr
2314
+ tngTableVirtualSpacer
2315
+ data-testid="virtual-bottom-spacer"
2316
+ [tngTableVirtualSpacerColspan]="3"
2317
+ [tngTableVirtualSpacerSize]="virtualRef.afterSize()"
2318
+ ></tr>
2319
+ }
2320
+ </tbody>
2321
+ </table>
2322
+ </div>
2323
+ `,
2324
+ }]
2325
+ }], propDecorators: { selectionRef: [{
2326
+ type: ViewChild,
2327
+ args: ['selectionRef']
2328
+ }], virtualRef: [{
2329
+ type: ViewChild,
2330
+ args: ['virtualRef', { static: true }]
2331
+ }] } });
2332
+ export class TableKeyboardHarnessComponent {
2333
+ rows = signal([
2334
+ { id: 'alpha', label: 'Alpha', status: 'Ready', value: 1 },
2335
+ { disabled: true, id: 'beta', label: 'Beta', status: 'Blocked', value: 2 },
2336
+ { id: 'gamma', label: 'Gamma', status: 'Draft', value: 3 },
2337
+ ], ...(ngDevMode ? [{ debugName: "rows" }] : []));
2338
+ showTable = signal(true, ...(ngDevMode ? [{ debugName: "showTable" }] : []));
2339
+ tableRef;
2340
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableKeyboardHarnessComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: TableKeyboardHarnessComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "tableRef", first: true, predicate: TngTable, descendants: true }], ngImport: i0, template: `
2342
+ <button type="button" data-testid="before">Before</button>
2343
+
2344
+ @if (showTable()) {
2345
+ <table tngTable data-testid="keyboard-table">
2346
+ <thead tngTableHeader>
2347
+ <tr tngTableRow>
2348
+ <th
2349
+ tngTableHeaderCell
2350
+ [tngTableColumnId]="'label'"
2351
+ data-testid="keyboard-cell-header-label"
2352
+ >
2353
+ Label
2354
+ </th>
2355
+ <th
2356
+ tngTableHeaderCell
2357
+ [tngTableColumnId]="'status'"
2358
+ data-testid="keyboard-cell-header-status"
2359
+ >
2360
+ Status
2361
+ </th>
2362
+ <th
2363
+ tngTableHeaderCell
2364
+ [tngTableColumnId]="'value'"
2365
+ data-testid="keyboard-cell-header-value"
2366
+ >
2367
+ Value
2368
+ </th>
2369
+ </tr>
2370
+ </thead>
2371
+
2372
+ <tbody tngTableBody>
2373
+ @for (row of rows(); track row.id) {
2374
+ <tr
2375
+ tngTableRow
2376
+ [tngTableRowDisabled]="row.disabled ?? false"
2377
+ [tngTableRowId]="row.id"
2378
+ >
2379
+ <td
2380
+ tngTableCell
2381
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-label'"
2382
+ [tngTableColumnId]="'label'"
2383
+ >
2384
+ {{ row.label }}
2385
+ </td>
2386
+ <td
2387
+ tngTableCell
2388
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-status'"
2389
+ [tngTableColumnId]="'status'"
2390
+ >
2391
+ {{ row.status }}
2392
+ </td>
2393
+ <td
2394
+ tngTableCell
2395
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-value'"
2396
+ [tngTableColumnId]="'value'"
2397
+ >
2398
+ {{ row.value }}
2399
+ </td>
2400
+ </tr>
2401
+ }
2402
+ </tbody>
2403
+ </table>
2404
+ }
2405
+
2406
+ <button type="button" data-testid="after">After</button>
2407
+ `, isInline: true, dependencies: [{ kind: "directive", type: TngTable, selector: "table[tngTable]", inputs: ["items", "error", "filterable", "tngTableLayout", "loading", "pageable", "rowId", "dir", "ariaLabel", "ariaLabelledby"], exportAs: ["tngTable"] }, { kind: "directive", type: TngTableHeader, selector: "thead[tngTableHeader]", inputs: ["tngTableHeaderSticky", "tngTableHeaderStickyOffset"], exportAs: ["tngTableHeader"] }, { kind: "directive", type: TngTableBody, selector: "tbody[tngTableBody]", exportAs: ["tngTableBody"] }, { kind: "directive", type: TngTableRow, selector: "tr[tngTableRow]", inputs: ["tngTableRowDisabled", "tngTableRowExpanded", "tngTableRowId", "tngTableRowSelected"], outputs: ["rowClick", "rowContextMenu"], exportAs: ["tngTableRow"] }, { kind: "directive", type: TngTableHeaderCell, selector: "th[tngTableHeaderCell]", inputs: ["tngTableColumnId", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], exportAs: ["tngTableHeaderCell"] }, { kind: "directive", type: TngTableCell, selector: "td[tngTableCell]", inputs: ["tngTableColumnId", "tngTableHeaders", "tngTableStickyColumn", "tngTableStickyOffset", "tngTableTruncate"], outputs: ["cellClick"], exportAs: ["tngTableCell"] }] });
2408
+ }
2409
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TableKeyboardHarnessComponent, decorators: [{
2410
+ type: Component,
2411
+ args: [{
2412
+ imports: [
2413
+ TngTable,
2414
+ TngTableHeader,
2415
+ TngTableBody,
2416
+ TngTableRow,
2417
+ TngTableHeaderCell,
2418
+ TngTableCell,
2419
+ ],
2420
+ template: `
2421
+ <button type="button" data-testid="before">Before</button>
2422
+
2423
+ @if (showTable()) {
2424
+ <table tngTable data-testid="keyboard-table">
2425
+ <thead tngTableHeader>
2426
+ <tr tngTableRow>
2427
+ <th
2428
+ tngTableHeaderCell
2429
+ [tngTableColumnId]="'label'"
2430
+ data-testid="keyboard-cell-header-label"
2431
+ >
2432
+ Label
2433
+ </th>
2434
+ <th
2435
+ tngTableHeaderCell
2436
+ [tngTableColumnId]="'status'"
2437
+ data-testid="keyboard-cell-header-status"
2438
+ >
2439
+ Status
2440
+ </th>
2441
+ <th
2442
+ tngTableHeaderCell
2443
+ [tngTableColumnId]="'value'"
2444
+ data-testid="keyboard-cell-header-value"
2445
+ >
2446
+ Value
2447
+ </th>
2448
+ </tr>
2449
+ </thead>
2450
+
2451
+ <tbody tngTableBody>
2452
+ @for (row of rows(); track row.id) {
2453
+ <tr
2454
+ tngTableRow
2455
+ [tngTableRowDisabled]="row.disabled ?? false"
2456
+ [tngTableRowId]="row.id"
2457
+ >
2458
+ <td
2459
+ tngTableCell
2460
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-label'"
2461
+ [tngTableColumnId]="'label'"
2462
+ >
2463
+ {{ row.label }}
2464
+ </td>
2465
+ <td
2466
+ tngTableCell
2467
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-status'"
2468
+ [tngTableColumnId]="'status'"
2469
+ >
2470
+ {{ row.status }}
2471
+ </td>
2472
+ <td
2473
+ tngTableCell
2474
+ [attr.data-testid]="'keyboard-cell-' + row.id + '-value'"
2475
+ [tngTableColumnId]="'value'"
2476
+ >
2477
+ {{ row.value }}
2478
+ </td>
2479
+ </tr>
2480
+ }
2481
+ </tbody>
2482
+ </table>
2483
+ }
2484
+
2485
+ <button type="button" data-testid="after">After</button>
2486
+ `,
2487
+ }]
2488
+ }], propDecorators: { tableRef: [{
2489
+ type: ViewChild,
2490
+ args: [TngTable]
2491
+ }] } });
2492
+ //# sourceMappingURL=tng-table.test-harness.js.map