@tekus/design-system 5.40.0 → 5.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 (43) hide show
  1. package/fesm2022/tekus-design-system-components-badge.mjs +19 -3
  2. package/fesm2022/tekus-design-system-components-badge.mjs.map +1 -1
  3. package/fesm2022/tekus-design-system-components-carousel.mjs +44 -9
  4. package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -1
  5. package/fesm2022/tekus-design-system-components-checkbox.mjs +2 -2
  6. package/fesm2022/tekus-design-system-components-checkbox.mjs.map +1 -1
  7. package/fesm2022/tekus-design-system-components-color-picker.mjs +119 -71
  8. package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
  9. package/fesm2022/tekus-design-system-components-column-picker.mjs +210 -0
  10. package/fesm2022/tekus-design-system-components-column-picker.mjs.map +1 -0
  11. package/fesm2022/tekus-design-system-components-dropdown.mjs +1 -1
  12. package/fesm2022/tekus-design-system-components-dropdown.mjs.map +1 -1
  13. package/fesm2022/tekus-design-system-components-icon.mjs +10 -0
  14. package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
  15. package/fesm2022/tekus-design-system-components-link-group.mjs +74 -0
  16. package/fesm2022/tekus-design-system-components-link-group.mjs.map +1 -0
  17. package/fesm2022/tekus-design-system-components-panel.mjs +2 -2
  18. package/fesm2022/tekus-design-system-components-panel.mjs.map +1 -1
  19. package/fesm2022/tekus-design-system-components-skeleton.mjs +79 -0
  20. package/fesm2022/tekus-design-system-components-skeleton.mjs.map +1 -0
  21. package/fesm2022/tekus-design-system-components-stepper.mjs +2 -2
  22. package/fesm2022/tekus-design-system-components-stepper.mjs.map +1 -1
  23. package/fesm2022/tekus-design-system-components-table.mjs +293 -11
  24. package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
  25. package/fesm2022/tekus-design-system-components-tabs.mjs +1 -1
  26. package/fesm2022/tekus-design-system-components-tabs.mjs.map +1 -1
  27. package/fesm2022/tekus-design-system-components-toggle.mjs +2 -2
  28. package/fesm2022/tekus-design-system-components-toggle.mjs.map +1 -1
  29. package/fesm2022/tekus-design-system-components-toolbar.mjs +33 -3
  30. package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
  31. package/fesm2022/tekus-design-system-components-tooltip.mjs +16 -3
  32. package/fesm2022/tekus-design-system-components-tooltip.mjs.map +1 -1
  33. package/package.json +13 -1
  34. package/types/tekus-design-system-components-badge.d.ts +15 -1
  35. package/types/tekus-design-system-components-carousel.d.ts +29 -3
  36. package/types/tekus-design-system-components-color-picker.d.ts +41 -7
  37. package/types/tekus-design-system-components-column-picker.d.ts +116 -0
  38. package/types/tekus-design-system-components-icon.d.ts +1 -1
  39. package/types/tekus-design-system-components-link-group.d.ts +119 -0
  40. package/types/tekus-design-system-components-skeleton.d.ts +68 -0
  41. package/types/tekus-design-system-components-table.d.ts +263 -8
  42. package/types/tekus-design-system-components-toolbar.d.ts +37 -2
  43. package/types/tekus-design-system-components-tooltip.d.ts +12 -1
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, viewChild, model, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { model, viewChild, input, output, computed, signal, inject, ElementRef, Injector, effect, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
3
4
  import * as i1 from 'primeng/table';
4
5
  import { TableModule } from 'primeng/table';
5
6
  import { TagModule } from 'primeng/tag';
@@ -11,8 +12,14 @@ import { ActionGroupComponent } from '@tekus/design-system/components/action-gro
11
12
  import { IconComponent } from '@tekus/design-system/components/icon';
12
13
  import { TimeAgoComponent } from '@tekus/design-system/components/time-ago';
13
14
  import { CounterComponent } from '@tekus/design-system/components/counter';
15
+ import { BadgeComponent } from '@tekus/design-system/components/badge';
16
+ import { ToggleComponent } from '@tekus/design-system/components/toggle';
17
+ import { TooltipComponent } from '@tekus/design-system/components/tooltip';
18
+ import { LinkGroupComponent } from '@tekus/design-system/components/link-group';
19
+ import { SkeletonComponent } from '@tekus/design-system/components/skeleton';
14
20
  import * as i2 from 'primeng/api';
15
21
 
22
+ const isObject = (value) => typeof value === 'object' && value !== null;
16
23
  /**
17
24
  * @component TableComponent
18
25
  * @description
@@ -27,10 +34,11 @@ import * as i2 from 'primeng/api';
27
34
  class TableComponent {
28
35
  constructor() {
29
36
  /**
30
- * @property {InputSignal<T[]>} data
37
+ * @property {ModelSignal<T[]>} data
31
38
  * @description
32
39
  * Array of data objects to display in the table rows.
33
40
  * Each object corresponds to one row; properties are mapped to columns via the `columns` input.
41
+ * Supports two-way binding `[(data)]` to synchronize row reordering.
34
42
  *
35
43
  * @default []
36
44
  *
@@ -40,7 +48,7 @@ class TableComponent {
40
48
  * { id: 2, name: 'Jane', status: 'inactive' }
41
49
  * ]"
42
50
  */
43
- this.data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
51
+ this.data = model([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
44
52
  /**
45
53
  * @property {viewChild} tableRef
46
54
  * @description
@@ -64,6 +72,46 @@ class TableComponent {
64
72
  * ]"
65
73
  */
66
74
  this.columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : /* istanbul ignore next */ []));
75
+ /**
76
+ * @property {InputSignal<boolean>} reorderableRows
77
+ * @description
78
+ * Whether row reordering is enabled.
79
+ * When true, an extra leading column with a `grip-vertical` handle is rendered for each row.
80
+ * Rows are moved by dragging the handle, or with ArrowUp / ArrowDown while it is focused.
81
+ * Reordering is paused (handle disabled) while a sort or a column filter is active,
82
+ * because the visible order would not match the underlying `data` order.
83
+ * Set it before the rows render: PrimeNG binds the drag listeners when each row is created.
84
+ * @default false
85
+ */
86
+ this.reorderableRows = input(false, ...(ngDevMode ? [{ debugName: "reorderableRows" }] : /* istanbul ignore next */ []));
87
+ /**
88
+ * @property {InputSignal<string>} reorderHandleLabel
89
+ * @description
90
+ * Accessible name of the row reorder handle and of its column header.
91
+ * @default 'Reordenar fila'
92
+ */
93
+ this.reorderHandleLabel = input('Reordenar fila', ...(ngDevMode ? [{ debugName: "reorderHandleLabel" }] : /* istanbul ignore next */ []));
94
+ /**
95
+ * @property {InputSignal<string>} reorderMovedLabel
96
+ * @description
97
+ * Screen reader announcement after a row is moved.
98
+ * `{0}` is replaced by the new position and `{1}` by the total of rows.
99
+ * @default 'Fila movida a la posición {0} de {1}'
100
+ */
101
+ this.reorderMovedLabel = input('Fila movida a la posición {0} de {1}', ...(ngDevMode ? [{ debugName: "reorderMovedLabel" }] : /* istanbul ignore next */ []));
102
+ /**
103
+ * @property {InputSignal<string | undefined>} imageLoadingLabel
104
+ * @description
105
+ * Optional screen reader text of an image cell in `loading` state, in the
106
+ * app's language. Without it the loading skeleton is decorative.
107
+ */
108
+ this.imageLoadingLabel = input(...(ngDevMode ? [undefined, { debugName: "imageLoadingLabel" }] : /* istanbul ignore next */ []));
109
+ /**
110
+ * @property {OutputEmitterRef<TableRowReorderEvent<T>>} rowReorder
111
+ * @description
112
+ * Emitted when a row is moved, by drag-and-drop or keyboard.
113
+ */
114
+ this.rowReorder = output();
67
115
  /**
68
116
  * @property {InputSignal<'single' | 'multiple' | undefined>} selectionMode
69
117
  * @description
@@ -82,9 +130,59 @@ class TableComponent {
82
130
  * Property name to uniquely identify a row.
83
131
  */
84
132
  this.dataKey = input(undefined, ...(ngDevMode ? [{ debugName: "dataKey" }] : /* istanbul ignore next */ []));
133
+ /**
134
+ * @property {InputSignal<string[]>} hiddenColumns
135
+ * @description
136
+ * Optional. `field` of the columns to hide. The consumer owns this list
137
+ * (e.g. bound to `tk-toolbar`'s `[(hiddenColumns)]` and preloaded from a saved
138
+ * preference). Fields that do not match a column are ignored, and columns
139
+ * without `field` (selection, actions) are always shown.
140
+ * Hiding a column does not clear its active filter.
141
+ * @default []
142
+ */
143
+ this.hiddenColumns = input([], ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
144
+ /**
145
+ * @computed visibleColumns
146
+ * @description
147
+ * Columns actually rendered: `columns` minus `hiddenColumns`.
148
+ */
149
+ this.visibleColumns = computed(() => {
150
+ const hidden = this.hiddenColumns();
151
+ const all = this.columns();
152
+ if (!hidden.length) {
153
+ return all;
154
+ }
155
+ return all.filter(col => !col.field || !hidden.includes(col.field));
156
+ }, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
157
+ /**
158
+ * @property {InputSignal<string | null>} minTableWidth
159
+ * @description
160
+ * CSS `min-width` applied to the underlying PrimeNG table. Pass `null` to
161
+ * remove the minimum entirely (e.g. inside a narrow container such as a
162
+ * wizard step or modal) so the table can shrink to fit instead of forcing
163
+ * horizontal overflow.
164
+ * @default '60rem'
165
+ */
166
+ this.minTableWidth = input('60rem', ...(ngDevMode ? [{ debugName: "minTableWidth" }] : /* istanbul ignore next */ []));
85
167
  this.initialData = signal([], ...(ngDevMode ? [{ debugName: "initialData" }] : /* istanbul ignore next */ []));
168
+ /**
169
+ * @property imageStatuses
170
+ * @description
171
+ * Load outcome of each image cell, per row object and column field. Keyed by
172
+ * the row (not the src) so rows sharing an image URL keep their own state,
173
+ * and a new row object always gets a fresh attempt.
174
+ */
175
+ this.imageStatuses = new WeakMap();
176
+ /** Bumped on every image load/error so the template re-reads the statuses */
177
+ this.imageStatusVersion = signal(0, ...(ngDevMode ? [{ debugName: "imageStatusVersion" }] : /* istanbul ignore next */ []));
86
178
  this.internalData = signal([], ...(ngDevMode ? [{ debugName: "internalData" }] : /* istanbul ignore next */ []));
87
179
  this.isSorted = signal(null, ...(ngDevMode ? [{ debugName: "isSorted" }] : /* istanbul ignore next */ []));
180
+ /** Text of the polite live region announced after a row is moved */
181
+ this.reorderAnnouncement = signal('', ...(ngDevMode ? [{ debugName: "reorderAnnouncement" }] : /* istanbul ignore next */ []));
182
+ /** Row offset applied by each reorder handle key */
183
+ this.reorderKeyDelta = { ArrowUp: -1, ArrowDown: 1 };
184
+ this.host = inject(ElementRef);
185
+ this.injector = inject(Injector);
88
186
  /** Tracks which column's filter overlay is currently open */
89
187
  this.activeFilterColumn = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterColumn" }] : /* istanbul ignore next */ []));
90
188
  /** Stores the selected filter value per column field (null = no filter) */
@@ -124,6 +222,16 @@ class TableComponent {
124
222
  const allSelected = this.isAllSelected();
125
223
  return !allSelected && selected.length > 0;
126
224
  }, ...(ngDevMode ? [{ debugName: "isPartiallySelected" }] : /* istanbul ignore next */ []));
225
+ /**
226
+ * @computed canReorderRows
227
+ * @description
228
+ * Rows can only be moved while the visible order matches `data`: reordering
229
+ * a sorted or filtered view would drop the hidden rows from the model or be
230
+ * undone by the next sort pass.
231
+ */
232
+ this.canReorderRows = computed(() => this.reorderableRows() &&
233
+ !this.sortField() &&
234
+ !Object.values(this.columnFilters()).some(value => value != null), ...(ngDevMode ? [{ debugName: "canReorderRows" }] : /* istanbul ignore next */ []));
127
235
  this.actionGroupCache = new Map();
128
236
  /**
129
237
  * @effect data → initialData sync
@@ -198,6 +306,61 @@ class TableComponent {
198
306
  updateSelection(value) {
199
307
  this.selection.set([...value]);
200
308
  }
309
+ /**
310
+ * @method onRowReorder
311
+ * @description
312
+ * Handles row reorder event from PrimeNG Table and synchronizes data.
313
+ * @param event {{ dragIndex?: number; dropIndex?: number }}
314
+ */
315
+ onRowReorder(event) {
316
+ if (event.dragIndex == null || event.dropIndex == null) {
317
+ return;
318
+ }
319
+ this.moveRow(event.dragIndex, event.dropIndex);
320
+ }
321
+ /**
322
+ * @method onReorderHandleKeydown
323
+ * @description
324
+ * Moves the row one position with ArrowUp / ArrowDown and keeps focus on its handle.
325
+ * Stops propagation so PrimeNG's selectable row does not treat the keys as row navigation or selection.
326
+ */
327
+ onReorderHandleKeydown(event, rowIndex) {
328
+ event.stopPropagation();
329
+ const delta = this.reorderKeyDelta[event.key];
330
+ if (!delta) {
331
+ return;
332
+ }
333
+ event.preventDefault();
334
+ const target = rowIndex + delta;
335
+ if (!this.moveRow(rowIndex, target)) {
336
+ return;
337
+ }
338
+ afterNextRender(() => {
339
+ const handles = this.host.nativeElement.querySelectorAll('.tk-table__row-reorder-handle button');
340
+ handles[target]?.focus();
341
+ }, { injector: this.injector });
342
+ }
343
+ /**
344
+ * Moves a row inside `data` (not the PrimeNG-mutated `internalData`), syncs the
345
+ * model and emits `rowReorder`. Returns false when the move is not allowed.
346
+ */
347
+ moveRow(fromIndex, toIndex) {
348
+ const rows = this.data();
349
+ if (!this.canReorderRows() ||
350
+ fromIndex === toIndex ||
351
+ fromIndex < 0 || toIndex < 0 ||
352
+ fromIndex >= rows.length || toIndex >= rows.length) {
353
+ return false;
354
+ }
355
+ const reordered = [...rows];
356
+ reordered.splice(toIndex, 0, reordered.splice(fromIndex, 1)[0]);
357
+ this.data.set(reordered);
358
+ this.reorderAnnouncement.set(this.reorderMovedLabel()
359
+ .replace('{0}', String(toIndex + 1))
360
+ .replace('{1}', String(reordered.length)));
361
+ this.rowReorder.emit({ dragIndex: fromIndex, dropIndex: toIndex, data: reordered });
362
+ return true;
363
+ }
201
364
  getActionGroup(actions, row) {
202
365
  if (!actions)
203
366
  return [];
@@ -468,21 +631,134 @@ class TableComponent {
468
631
  }
469
632
  col.counterChange?.(row, value);
470
633
  }
634
+ /**
635
+ * @method isToggleDisabled
636
+ * @description
637
+ * Resolves a toggle column's `toggleDisabled`, which may be a boolean or a
638
+ * per-row predicate — the same shape `isCounterDisabled` already accepts.
639
+ * @param col {TableColumn<T>} - The toggle column definition.
640
+ * @param row {T} - The data row being rendered.
641
+ * @returns Whether this row's toggle should be disabled.
642
+ */
643
+ isToggleDisabled(col, row) {
644
+ return typeof col.toggleDisabled === 'function'
645
+ ? col.toggleDisabled(row)
646
+ : (col.toggleDisabled ?? false);
647
+ }
648
+ /**
649
+ * @method onToggleChange
650
+ * @description
651
+ * Writes a toggle cell's new value into the row and notifies the consumer.
652
+ * Mutating the row in place matches how the `checkbox` column type behaves.
653
+ * @param col {TableColumn<T>} - The toggle column definition.
654
+ * @param row {T} - The data row being edited.
655
+ * @param value {boolean} - The new switch value.
656
+ */
657
+ onToggleChange(col, row, value) {
658
+ if (col.field) {
659
+ row[col.field] = value;
660
+ }
661
+ col.toggleChange?.(row, value);
662
+ }
663
+ /**
664
+ * @method getImageCount
665
+ * @description
666
+ * Resolves how many images are available for an image-type cell via the
667
+ * column's `imageCount` callback. Returns 0 when not configured, so the
668
+ * template only overlays a `tk-badge` when there is more than one image.
669
+ * @param col {TableColumn<T>} - The image column definition.
670
+ * @param row {T} - The data row being rendered.
671
+ */
672
+ getImageCount(col, row) {
673
+ return col.imageCount ? col.imageCount(row) : 0;
674
+ }
471
675
  /**
472
676
  * @method onImageError
473
677
  * @description
474
- * Handles image load errors by replacing the broken src with a fallback URL.
678
+ * Handles image load errors: switches to the column's `imageFallback` once;
679
+ * if there is none, or it fails too, the cell shows the error placeholder.
475
680
  * Called from the template's (error) binding on image-type columns.
476
681
  * @param event {Event} - The native error event from the <img> element.
477
- * @param fallback {string | undefined} - Optional URL to use as replacement src.
682
+ * @param col {TableColumn<T>} - The image column definition.
683
+ * @param row {T} - The data row being rendered.
478
684
  */
479
- onImageError(event, fallback) {
480
- if (fallback) {
481
- event.target.src = fallback;
685
+ onImageError(event, col, row) {
686
+ const img = event.target;
687
+ const fallback = col.imageFallback;
688
+ if (fallback && img.getAttribute('src') !== fallback) {
689
+ img.src = fallback;
690
+ return;
691
+ }
692
+ this.setImageStatus(col, row, 'failed');
693
+ }
694
+ /**
695
+ * @method onImageLoad
696
+ * @description
697
+ * Marks an image cell as loaded so its skeleton is removed.
698
+ * @param col {TableColumn<T>} - The image column definition.
699
+ * @param row {T} - The data row being rendered.
700
+ */
701
+ onImageLoad(col, row) {
702
+ this.setImageStatus(col, row, 'loaded');
703
+ }
704
+ /**
705
+ * @method getImageState
706
+ * @description
707
+ * State of an image cell: the column's `imageState` when it is `loading` or
708
+ * `error`; otherwise `error` if the image failed to load, else `default`.
709
+ * A `loading` or `error` state from the column clears the load outcome, so
710
+ * the image is retried (with a skeleton) when the cell goes back to `default`.
711
+ * @param col {TableColumn<T>} - The image column definition.
712
+ * @param row {T} - The data row being rendered.
713
+ */
714
+ getImageState(col, row) {
715
+ this.imageStatusVersion();
716
+ const state = col.imageState?.(row) ?? 'default';
717
+ if (state !== 'default') {
718
+ // Plain write, not a signal: safe during render and seen by the next one
719
+ this.clearImageStatus(col, row);
720
+ return state;
721
+ }
722
+ return this.getImageStatus(col, row) === 'failed' ? 'error' : 'default';
723
+ }
724
+ /**
725
+ * @method isImageLoaded
726
+ * @description
727
+ * Whether the image of a cell finished loading. A cell without src counts
728
+ * as loaded, so it never shows an endless skeleton.
729
+ * @param col {TableColumn<T>} - The image column definition.
730
+ * @param row {T} - The data row being rendered.
731
+ */
732
+ isImageLoaded(col, row) {
733
+ this.imageStatusVersion();
734
+ return !this.getImageSrc(col, row) || this.getImageStatus(col, row) === 'loaded';
735
+ }
736
+ getImageSrc(col, row) {
737
+ const value = col.field ? row[col.field] : undefined;
738
+ return typeof value === 'string' ? value : '';
739
+ }
740
+ getImageStatus(col, row) {
741
+ const src = this.getImageSrc(col, row);
742
+ const entry = col.field && src && isObject(row) ? this.imageStatuses.get(row)?.get(col.field) : undefined;
743
+ return entry?.src === src ? entry.status : null;
744
+ }
745
+ setImageStatus(col, row, status) {
746
+ const src = this.getImageSrc(col, row);
747
+ if (!col.field || !src || !isObject(row)) {
748
+ return;
749
+ }
750
+ const cells = this.imageStatuses.get(row) ?? new Map();
751
+ cells.set(col.field, { src, status });
752
+ this.imageStatuses.set(row, cells);
753
+ this.imageStatusVersion.update(version => version + 1);
754
+ }
755
+ clearImageStatus(col, row) {
756
+ if (col.field && isObject(row)) {
757
+ this.imageStatuses.get(row)?.delete(col.field);
482
758
  }
483
759
  }
484
760
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
485
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: true, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selection: "selectionChange", columnFilters: "columnFiltersChange", sortField: "sortFieldChange", sortOrder: "sortOrderChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"{ 'min-width': '60rem' }\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td>{{ row[col.field!] }}</td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}\n", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "hint", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible", "disabled"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: TimeAgoComponent, selector: "tk-time-ago", inputs: ["dateTime", "severity", "tooltipText", "tooltipFormat"] }, { kind: "component", type: CounterComponent, selector: "tk-counter", inputs: ["value", "min", "max", "step", "disabled", "readonly", "control", "decreaseLabel", "increaseLabel", "ariaLabel", "ariaLabelledby"], outputs: ["valueChange", "disabledChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
761
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: TableComponent, isStandalone: true, selector: "tk-table", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, reorderableRows: { classPropertyName: "reorderableRows", publicName: "reorderableRows", isSignal: true, isRequired: false, transformFunction: null }, reorderHandleLabel: { classPropertyName: "reorderHandleLabel", publicName: "reorderHandleLabel", isSignal: true, isRequired: false, transformFunction: null }, reorderMovedLabel: { classPropertyName: "reorderMovedLabel", publicName: "reorderMovedLabel", isSignal: true, isRequired: false, transformFunction: null }, imageLoadingLabel: { classPropertyName: "imageLoadingLabel", publicName: "imageLoadingLabel", isSignal: true, isRequired: false, transformFunction: null }, selectionMode: { classPropertyName: "selectionMode", publicName: "selectionMode", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, hiddenColumns: { classPropertyName: "hiddenColumns", publicName: "hiddenColumns", isSignal: true, isRequired: false, transformFunction: null }, minTableWidth: { classPropertyName: "minTableWidth", publicName: "minTableWidth", isSignal: true, isRequired: false, transformFunction: null }, columnFilters: { classPropertyName: "columnFilters", publicName: "columnFilters", isSignal: true, isRequired: false, transformFunction: null }, sortField: { classPropertyName: "sortField", publicName: "sortField", isSignal: true, isRequired: false, transformFunction: null }, sortOrder: { classPropertyName: "sortOrder", publicName: "sortOrder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { data: "dataChange", rowReorder: "rowReorder", selection: "selectionChange", columnFilters: "columnFiltersChange", sortField: "sortFieldChange", sortOrder: "sortOrderChange" }, viewQueries: [{ propertyName: "tableRef", first: true, predicate: ["tableRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\"\n (onRowReorder)=\"onRowReorder($event)\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @if (reorderableRows()) {\n <th class=\"tk-table__row-reorder-th\" scope=\"col\">\n <span class=\"tk-table__sr-only\">{{ reorderHandleLabel() }}</span>\n </th>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row let-rowIndex=\"rowIndex\">\n <tr [pSelectableRow]=\"row\" [pReorderableRow]=\"rowIndex\" [pReorderableRowDisabled]=\"!reorderableRows()\">\n @if (reorderableRows()) {\n <td class=\"tk-table__row-reorder-td\">\n <!-- Without pReorderableRowHandle PrimeNG never makes the row draggable -->\n @if (canReorderRows()) {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n pReorderableRowHandle\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onReorderHandleKeydown($event, rowIndex)\" />\n } @else {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n [disabled]=\"true\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n }\n </td>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n @let imageState = getImageState(col, row);\n @let imageWidth = col.imageWidth ?? '40px';\n @let imageHeight = col.imageHeight ?? '40px';\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n @switch (imageState) {\n @case ('loading') {\n <tk-skeleton\n class=\"tk-table__cell-img-skeleton\"\n [width]=\"imageWidth\"\n [height]=\"imageHeight\"\n [ariaLabel]=\"imageLoadingLabel()\" />\n }\n @case ('error') {\n @let errorTooltip = col.imageErrorTooltip ? col.imageErrorTooltip(row) : '';\n @if (errorTooltip) {\n <tk-tooltip [content]=\"errorTooltip\">\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: errorTooltip }\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: col.imageAlt ? col.imageAlt(row) : '' }\" />\n }\n <ng-template #imgError let-label>\n @let errorAction = imageCount > 1 && !!col.imageAction;\n <span\n class=\"tk-table__cell-img-error\"\n [class.tk-table__cell-img-error--clickable]=\"errorAction\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"errorAction ? 0 : null\"\n [attr.role]=\"errorAction ? 'button' : null\"\n (click)=\"errorAction && handleImageClick($event, col, row)\"\n (keydown.enter)=\"errorAction && col.imageAction!(row)\">\n <tk-icon aria-hidden=\"true\" icon=\"triangle-exclamation\" styleIcon=\"regular\" />\n @if (label) {\n <span class=\"tk-table__sr-only\">{{ label }}</span>\n }\n </span>\n </ng-template>\n }\n @default {\n @let imageLoaded = isImageLoaded(col, row);\n <span class=\"tk-table__cell-img-frame\">\n @if (!imageLoaded) {\n <tk-skeleton class=\"tk-table__cell-img-skeleton tk-table__cell-img-skeleton--overlay\" height=\"100%\" />\n }\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [class.tk-table__cell-img--pending]=\"!imageLoaded\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (load)=\"onImageLoad(col, row)\"\n (error)=\"onImageError($event, col, row)\"\n />\n </span>\n }\n }\n </ng-template>\n </td>\n }\n\n <!-- LINKS -->\n @if (col.type === 'links') {\n <td>\n <tk-link-group\n class=\"tk-table__cell-links\"\n [links]=\"col.links ? col.links(row) : []\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n@if (reorderableRows()) {\n<span class=\"tk-table__sr-only\" aria-live=\"polite\">{{ reorderAnnouncement() }}</span>\n}\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .p-datatable-row-reorder-indicator-up,:host ::ng-deep .p-datatable-row-reorder-indicator-down{position:absolute;color:var(--tk-primary-500, #16006f);z-index:10}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__cell-img--pending{opacity:0}.tk-table__cell-img-frame{position:relative;display:inline-flex}.tk-table__cell-img-skeleton--overlay{position:absolute;inset:0}.tk-table__cell-img-error{position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-strong, #cf2604)}.tk-table__cell-img-error--clickable{cursor:pointer}.tk-table__cell-links{max-width:100%}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__row-reorder-th,.tk-table__row-reorder-td{width:3rem!important;text-align:center;padding:.625rem .25rem!important}.tk-table__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled){cursor:grab}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled):active{cursor:grabbing}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: TableModule }, { kind: "component", type: i1.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i1.SortableColumn, selector: "[pSortableColumn]", inputs: ["pSortableColumn", "pSortableColumnDisabled"] }, { kind: "directive", type: i1.SelectableRow, selector: "[pSelectableRow]", inputs: ["pSelectableRow", "pSelectableRowIndex", "pSelectableRowDisabled"] }, { kind: "component", type: i1.SortIcon, selector: "p-sortIcon", inputs: ["field"] }, { kind: "directive", type: i1.ReorderableRowHandle, selector: "[pReorderableRowHandle]" }, { kind: "directive", type: i1.ReorderableRow, selector: "[pReorderableRow]", inputs: ["pReorderableRow", "pReorderableRowDisabled"] }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: TagComponent, selector: "tk-tag", inputs: ["value", "severity", "truncationLimit"] }, { kind: "component", type: ButtonComponent, selector: "tk-button", inputs: ["label", "disabled", "type", "severity", "variant", "link", "icon", "iconPosition", "tooltipText", "full", "ariaLabel", "size"], outputs: ["clicked"] }, { kind: "component", type: CheckboxComponent, selector: "tk-checkbox", inputs: ["model", "value", "label", "name", "inputId", "binary", "control", "errorMessage", "hint", "indeterminate", "disabled"], outputs: ["modelChange", "indeterminateChange", "disabledChange"] }, { kind: "component", type: ActionGroupComponent, selector: "tk-action-group", inputs: ["actions", "maxVisible", "disabled"] }, { kind: "component", type: IconComponent, selector: "tk-icon", inputs: ["icon", "styleIcon", "color", "size", "disabled"] }, { kind: "component", type: TimeAgoComponent, selector: "tk-time-ago", inputs: ["dateTime", "severity", "tooltipText", "tooltipFormat"] }, { kind: "component", type: CounterComponent, selector: "tk-counter", inputs: ["value", "min", "max", "step", "disabled", "readonly", "control", "decreaseLabel", "increaseLabel", "ariaLabel", "ariaLabelledby"], outputs: ["valueChange", "disabledChange"] }, { kind: "component", type: BadgeComponent, selector: "tk-badge", inputs: ["value", "severity", "overlay"] }, { kind: "component", type: ToggleComponent, selector: "tk-toggle", inputs: ["model", "label", "name", "inputId", "control", "errorMessage", "hint", "disabled"], outputs: ["modelChange", "disabledChange"] }, { kind: "component", type: TooltipComponent, selector: "tk-tooltip", inputs: ["content", "position", "lineClamp"] }, { kind: "component", type: LinkGroupComponent, selector: "tk-link-group", inputs: ["links"] }, { kind: "component", type: SkeletonComponent, selector: "tk-skeleton", inputs: ["width", "height", "shape", "size", "borderRadius", "animation", "ariaLabel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
486
762
  }
487
763
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, decorators: [{
488
764
  type: Component,
@@ -497,8 +773,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
497
773
  IconComponent,
498
774
  TimeAgoComponent,
499
775
  CounterComponent,
500
- ], template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"{ 'min-width': '60rem' }\" responsiveLayout=\"scroll\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @for (col of columns(); track col.header) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row>\n <tr [pSelectableRow]=\"row\">\n @for (col of columns(); track col.header) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td>{{ row[col.field!] }}</td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"col.imageWidth ?? '40px'\"\n [style.height]=\"col.imageHeight ?? '40px'\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (error)=\"onImageError($event, col.imageFallback)\"\n />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}\n", styles: [":host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
501
- }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], tableRef: [{ type: i0.ViewChild, args: ['tableRef', { isSignal: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], sortField: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortField", required: false }] }, { type: i0.Output, args: ["sortFieldChange"] }], sortOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortOrder", required: false }] }, { type: i0.Output, args: ["sortOrderChange"] }] } });
776
+ BadgeComponent,
777
+ ToggleComponent,
778
+ TooltipComponent,
779
+ LinkGroupComponent,
780
+ SkeletonComponent,
781
+ NgTemplateOutlet,
782
+ ], template: "<p-table #tableRef [selection]=\"selection()\" (selectionChange)=\"updateSelection($any($event))\"\n [selectionMode]=\"selectionMode()\" [dataKey]=\"dataKey()\" [value]=\"internalData()\" [customSort]=\"true\"\n (sortFunction)=\"customSort($event)\" [tableStyle]=\"minTableWidth() ? { 'min-width': minTableWidth() } : {}\" responsiveLayout=\"scroll\"\n (onRowReorder)=\"onRowReorder($event)\">\n <!-- HEADER -->\n <ng-template pTemplate=\"header\">\n <tr>\n @if (reorderableRows()) {\n <th class=\"tk-table__row-reorder-th\" scope=\"col\">\n <span class=\"tk-table__sr-only\">{{ reorderHandleLabel() }}</span>\n </th>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <th [id]=\"col.field\" [style.width]=\"col.width\"\n [pSortableColumn]=\"col.sortable ? col.field : undefined\"\n [class.tk-table__header--active]=\"activeFilterColumn() === col.field || isColumnFiltered(col.field!)\">\n <div class=\"tk-table__header-content\">\n @if (col.type === 'selection' && selectionMode() === 'multiple') {\n <div class=\"tk-table__actions hide-validation-messages\">\n <tk-checkbox [binary]=\"true\" [model]=\"isAllSelected()\" [indeterminate]=\"isPartiallySelected()\"\n (click)=\"$event.stopPropagation()\" (keypress)=\"$event.stopPropagation()\"\n (modelChange)=\"toggleAll($event)\"></tk-checkbox>\n </div>\n } @else if (col.type !== 'selection') {\n <span class=\"tk-table__header-label\">{{ col.header }}</span>\n @if (col.sortable) {\n <p-sortIcon [field]=\"col.field\"></p-sortIcon>\n }\n @if (col.filterable && col.field) {\n <button\n class=\"tk-table__filter-trigger\"\n [class.tk-table__filter-trigger--active]=\"isColumnFiltered(col.field)\"\n (click)=\"toggleFilterOverlay(col.field, $event)\"\n type=\"button\"\n [attr.aria-label]=\"'Filter ' + col.header\">\n <tk-icon icon=\"filter\" size=\"sm\"></tk-icon>\n </button>\n }\n }\n </div>\n </th>\n }\n </tr>\n </ng-template>\n\n <!-- BODY -->\n <ng-template pTemplate=\"body\" let-row let-rowIndex=\"rowIndex\">\n <tr [pSelectableRow]=\"row\" [pReorderableRow]=\"rowIndex\" [pReorderableRowDisabled]=\"!reorderableRows()\">\n @if (reorderableRows()) {\n <td class=\"tk-table__row-reorder-td\">\n <!-- Without pReorderableRowHandle PrimeNG never makes the row draggable -->\n @if (canReorderRows()) {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n pReorderableRowHandle\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"onReorderHandleKeydown($event, rowIndex)\" />\n } @else {\n <tk-button\n class=\"tk-table__row-reorder-handle\"\n icon=\"grip-vertical\"\n severity=\"secondary\"\n variant=\"text\"\n size=\"small\"\n [ariaLabel]=\"reorderHandleLabel()\"\n [disabled]=\"true\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n }\n </td>\n }\n @for (col of visibleColumns(); track col.field ?? $index) {\n <!-- SELECTION -->\n @if (col.type === 'selection') {\n <td>\n @if (selectionMode() === 'multiple') {\n <tk-checkbox [model]=\"selection()\" [value]=\"row\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (modelChange)=\"updateSelection($any($event))\"></tk-checkbox>\n }\n </td>\n }\n\n <!-- CHECKBOX (Boolean field) -->\n @if (col.type === 'checkbox') {\n <td>\n <tk-checkbox [binary]=\"true\" [(model)]=\"row[col.field!]\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"></tk-checkbox>\n </td>\n }\n\n <!-- COUNTER (editable integer field) -->\n @if (col.type === 'counter') {\n <td>\n <tk-counter\n [value]=\"$any(row[col.field!]) ?? 0\"\n [min]=\"col.counterMin ?? 0\"\n [max]=\"col.counterMax ?? 99\"\n [step]=\"col.counterStep ?? 1\"\n [disabled]=\"isCounterDisabled(col, row)\"\n [ariaLabel]=\"col.counterAriaLabel ? col.counterAriaLabel(row) : col.header\"\n [decreaseLabel]=\"col.counterDecreaseLabel ?? 'Decrease'\"\n [increaseLabel]=\"col.counterIncreaseLabel ?? 'Increase'\"\n (valueChange)=\"onCounterChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-counter>\n </td>\n }\n\n <!-- TOGGLE (Boolean field, switch) -->\n @if (col.type === 'toggle') {\n <td>\n @if (col.toggleTooltip) {\n <tk-tooltip [content]=\"col.toggleTooltip(row, $any(row[col.field!]) ?? false)\">\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"toggleSwitch\" />\n }\n <ng-template #toggleSwitch>\n <tk-toggle\n [model]=\"$any(row[col.field!]) ?? false\"\n [disabled]=\"isToggleDisabled(col, row)\"\n [label]=\"col.toggleLabel ? col.toggleLabel(row) : ''\"\n (modelChange)=\"onToggleChange(col, row, $event)\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\"></tk-toggle>\n </ng-template>\n </td>\n }\n\n <!-- TEXT (default) -->\n @if (!col.type || col.type === 'text') {\n <td\n [class.tk-table__cell--truncate]=\"col.truncate\"\n [style.max-width]=\"col.truncate ? (col.width ?? '200px') : null\">\n @if (col.icon) {\n <span class=\"tk-table__cell-icon-text\">\n <tk-icon [icon]=\"col.icon(row)\" [color]=\"col.iconColor ? col.iconColor(row) : undefined\" size=\"sm\" />\n <span>{{ row[col.field!] }}</span>\n </span>\n } @else {\n {{ row[col.field!] }}\n }\n </td>\n }\n\n <!-- TAG -->\n @if (col.type === 'tag') {\n <td>\n <tk-tag [value]=\"row[col.field!]\" [severity]=\"col.tagSeverity!(row)\" />\n </td>\n }\n\n <!-- ACTIONS -->\n @if (col.type === 'actions') {\n <td>\n <div class=\"tk-table__actions\">\n @for (action of col.actions!; track action.icon) {\n <tk-button [icon]=\"action.icon\" severity=\"secondary\" (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\" (clicked)=\"action?.action(row)\"></tk-button>\n }\n </div>\n </td>\n }\n\n <!-- ACTION GROUP -->\n @if (col.type === 'action-group') {\n <td>\n <div class=\"tk-table__actions\">\n <tk-action-group\n [actions]=\"getActionGroup(col.actionGroup!, row)\"\n [maxVisible]=\"col.actionGroupMaxVisible ?? 2\"\n [disabled]=\"col.actionGroupDisabled ?? false\"\n (click)=\"$event.stopPropagation()\"\n (keypress)=\"$event.stopPropagation()\"\n ></tk-action-group>\n </div>\n </td>\n }\n\n <!-- CONNECTION STATUS -->\n @if (col.type === 'connection-status') {\n <td>\n <tk-time-ago\n [dateTime]=\"row[col.field!]\"\n [severity]=\"col.connectionStatusSeverity ? col.connectionStatusSeverity(row) : 'success'\"\n [tooltipText]=\"col.connectionStatusTooltipText ? col.connectionStatusTooltipText(row) : undefined\" />\n </td>\n }\n\n <!-- IMAGE -->\n @if (col.type === 'image') {\n <td>\n @let imageState = getImageState(col, row);\n @let imageWidth = col.imageWidth ?? '40px';\n @let imageHeight = col.imageHeight ?? '40px';\n <div class=\"tk-table__cell-img-wrapper\">\n @let imageCount = getImageCount(col, row);\n @if (imageCount > 1) {\n <tk-badge\n [value]=\"imageCount + ''\"\n [severity]=\"col.imageCountSeverity ? col.imageCountSeverity(row) : 'primary'\"\n [overlay]=\"true\">\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n </tk-badge>\n } @else {\n <ng-container [ngTemplateOutlet]=\"cellImg\" />\n }\n </div>\n <ng-template #cellImg>\n @switch (imageState) {\n @case ('loading') {\n <tk-skeleton\n class=\"tk-table__cell-img-skeleton\"\n [width]=\"imageWidth\"\n [height]=\"imageHeight\"\n [ariaLabel]=\"imageLoadingLabel()\" />\n }\n @case ('error') {\n @let errorTooltip = col.imageErrorTooltip ? col.imageErrorTooltip(row) : '';\n @if (errorTooltip) {\n <tk-tooltip [content]=\"errorTooltip\">\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: errorTooltip }\" />\n </tk-tooltip>\n } @else {\n <ng-container [ngTemplateOutlet]=\"imgError\" [ngTemplateOutletContext]=\"{ $implicit: col.imageAlt ? col.imageAlt(row) : '' }\" />\n }\n <ng-template #imgError let-label>\n @let errorAction = imageCount > 1 && !!col.imageAction;\n <span\n class=\"tk-table__cell-img-error\"\n [class.tk-table__cell-img-error--clickable]=\"errorAction\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"errorAction ? 0 : null\"\n [attr.role]=\"errorAction ? 'button' : null\"\n (click)=\"errorAction && handleImageClick($event, col, row)\"\n (keydown.enter)=\"errorAction && col.imageAction!(row)\">\n <tk-icon aria-hidden=\"true\" icon=\"triangle-exclamation\" styleIcon=\"regular\" />\n @if (label) {\n <span class=\"tk-table__sr-only\">{{ label }}</span>\n }\n </span>\n </ng-template>\n }\n @default {\n @let imageLoaded = isImageLoaded(col, row);\n <span class=\"tk-table__cell-img-frame\">\n @if (!imageLoaded) {\n <tk-skeleton class=\"tk-table__cell-img-skeleton tk-table__cell-img-skeleton--overlay\" height=\"100%\" />\n }\n <img\n class=\"tk-table__cell-img\"\n [class.tk-table__cell-img--clickable]=\"!!col.imageAction\"\n [class.tk-table__cell-img--pending]=\"!imageLoaded\"\n [src]=\"row[col.field!]\"\n [alt]=\"col.imageAlt ? col.imageAlt(row) : ''\"\n [style.width]=\"imageWidth\"\n [style.height]=\"imageHeight\"\n [attr.tabindex]=\"col.imageAction ? 0 : null\"\n [attr.role]=\"col.imageAction ? 'button' : null\"\n (click)=\"handleImageClick($event, col, row)\"\n (keydown.enter)=\"col.imageAction && col.imageAction(row)\"\n (load)=\"onImageLoad(col, row)\"\n (error)=\"onImageError($event, col, row)\"\n />\n </span>\n }\n }\n </ng-template>\n </td>\n }\n\n <!-- LINKS -->\n @if (col.type === 'links') {\n <td>\n <tk-link-group\n class=\"tk-table__cell-links\"\n [links]=\"col.links ? col.links(row) : []\"\n (click)=\"$event.stopPropagation()\"\n (keydown)=\"$event.stopPropagation()\" />\n </td>\n }\n }\n </tr>\n </ng-template>\n</p-table>\n\n@if (reorderableRows()) {\n<span class=\"tk-table__sr-only\" aria-live=\"polite\">{{ reorderAnnouncement() }}</span>\n}\n\n<!-- Filter Overlay rendered outside the table to avoid overflow clipping -->\n@if (activeFilterColumn()) {\n<div class=\"tk-table__filter-backdrop\"\n tabindex=\"-1\"\n (click)=\"closeFilterOverlay()\"\n (keydown.escape)=\"closeFilterOverlay()\"></div>\n<div\n class=\"tk-table__filter-overlay\"\n tabindex=\"-1\"\n [style.top.px]=\"filterOverlayPosition().top\"\n [style.left.px]=\"filterOverlayPosition().left\"\n (click)=\"$event.stopPropagation()\"\n (keydown.escape)=\"closeFilterOverlay()\">\n <div class=\"tk-table__filter-list\">\n @for (option of getUniqueColumnValues(activeFilterColumn()!); track option) {\n <button\n class=\"tk-table__filter-option\"\n [class.tk-table__filter-option--selected]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n type=\"button\"\n [attr.aria-pressed]=\"getActiveFilterValue(activeFilterColumn()!) === option\"\n (click)=\"selectFilterValue(activeFilterColumn()!, option)\">\n {{ option }}\n </button>\n }\n </div>\n @if (isColumnFiltered(activeFilterColumn()!)) {\n <div class=\"tk-table__filter-clear\">\n <button\n class=\"tk-table__filter-clear-btn\"\n type=\"button\"\n (click)=\"clearFilter(activeFilterColumn()!)\">\n Clear filter\n </button>\n </div>\n }\n</div>\n}", styles: [":host{display:block;min-width:0}:host ::ng-deep .p-datatable-column-sorted{background-color:var(--tk-primary-100, #b7b0d2)!important;color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-column-sorted svg{color:var(--tk-primary-700, #10004f)!important}:host ::ng-deep .p-datatable-sortable-column{font-size:var(--tk-font-size-sm, .875rem);color:var(--tk-surface-950, #191a1b);padding:.625rem}:host ::ng-deep .p-datatable-sortable-column svg{color:var(--tk-surface-500, #424243)}:host ::ng-deep .p-button-secondary{background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-0, #ffffff)}:host ::ng-deep .p-datatable-tbody td{color:var(--tk-surface-950, #191a1b);font-size:var(--tk-font-size-sm, .875rem);padding:.625rem}:host ::ng-deep .tk-table__cell--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .p-datatable-row-reorder-indicator-up,:host ::ng-deep .p-datatable-row-reorder-indicator-down{position:absolute;color:var(--tk-primary-500, #16006f);z-index:10}.tk-table__cell-icon-text{display:inline-flex;align-items:center;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__cell-img-wrapper{display:inline-flex}.tk-table__cell-img{display:block;object-fit:cover}.tk-table__cell-img--clickable{cursor:pointer}.tk-table__cell-img--pending{opacity:0}.tk-table__cell-img-frame{position:relative;display:inline-flex}.tk-table__cell-img-skeleton--overlay{position:absolute;inset:0}.tk-table__cell-img-error{position:relative;display:inline-flex;align-items:center;justify-content:center;border-radius:var(--tk-borderRadius-xs, .25rem);background:var(--tk-color-feedback-danger-muted, #ffddd4);color:var(--tk-color-feedback-danger-strong, #cf2604)}.tk-table__cell-img-error--clickable{cursor:pointer}.tk-table__cell-links{max-width:100%}.tk-table__actions{display:flex;gap:var(--tk-spacing-gap-xs, .25rem)}.tk-table__header-content{display:flex;align-items:center;gap:.25rem;width:100%}.tk-table__header-label{white-space:nowrap}.tk-table__header--active{background-color:var(--tk-primary-100, #b7b0d2)!important}.tk-table__row-reorder-th,.tk-table__row-reorder-td{width:3rem!important;text-align:center;padding:.625rem .25rem!important}.tk-table__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled){cursor:grab}.tk-table__row-reorder-handle ::ng-deep .p-button:not(:disabled):active{cursor:grabbing}.tk-table__filter-trigger{display:inline-flex;align-items:center;justify-content:center;width:1.5rem;height:1.5rem;border:none;background:transparent;border-radius:var(--tk-border-radius-xs, 4px);cursor:pointer;color:var(--tk-surface-500, #8a8a8b);transition:background-color .2s,color .2s;padding:0;margin-left:auto}.tk-table__filter-trigger:hover{background-color:var(--tk-surface-200, #e4e4e4);color:var(--tk-surface-700, #424243)}.tk-table__filter-trigger--active{color:var(--tk-primary-700, #10004f);background-color:var(--tk-primary-50, #e8e6f1)}.tk-table__filter-trigger--active:hover{background-color:var(--tk-primary-100, #b7b0d2);color:var(--tk-primary-700, #10004f)}.tk-table__filter-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999;background:transparent}.tk-table__filter-overlay{position:fixed;z-index:1000;min-width:10rem;max-height:15rem;background-color:var(--tk-surface-0, #ffffff);border:1px solid var(--tk-surface-200, #e4e4e4);border-radius:var(--tk-border-radius-s, 8px);box-shadow:0 4px 16px #0000001f;overflow:hidden;display:flex;flex-direction:column;animation:tk-filter-fade-in .15s ease-out}.tk-table__filter-list{margin:0;padding:.25rem 0;overflow-y:auto;max-height:12rem;display:flex;flex-direction:column}.tk-table__filter-option{display:block;width:100%;padding:.5rem .75rem;font-size:.875rem;color:var(--tk-surface-950, #191a1b);cursor:pointer;transition:background-color .15s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;border:none;background:transparent;text-align:left}.tk-table__filter-option:hover{background-color:var(--tk-surface-100, #f2f1f1)}.tk-table__filter-option--selected{background-color:var(--tk-primary-50, #e8e6f1);color:var(--tk-primary-700, #10004f);font-weight:600}.tk-table__filter-option--selected:hover{background-color:var(--tk-primary-100, #b7b0d2)}.tk-table__filter-clear{border-top:1px solid var(--tk-surface-200, #e4e4e4);padding:.375rem .75rem;display:flex;justify-content:center}.tk-table__filter-clear-btn{background:transparent;border:none;color:var(--tk-primary-500, #16006f);font-size:.8125rem;font-weight:600;cursor:pointer;padding:.25rem .5rem;border-radius:var(--tk-border-radius-xs, 4px);transition:background-color .15s}.tk-table__filter-clear-btn:hover{background-color:var(--tk-primary-50, #e8e6f1)}:host ::ng-deep .p-datatable-thead>tr>th{position:relative}@keyframes tk-filter-fade-in{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
783
+ }], ctorParameters: () => [], propDecorators: { data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }, { type: i0.Output, args: ["dataChange"] }], tableRef: [{ type: i0.ViewChild, args: ['tableRef', { isSignal: true }] }], columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], reorderableRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderableRows", required: false }] }], reorderHandleLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderHandleLabel", required: false }] }], reorderMovedLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "reorderMovedLabel", required: false }] }], imageLoadingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageLoadingLabel", required: false }] }], rowReorder: [{ type: i0.Output, args: ["rowReorder"] }], selectionMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectionMode", required: false }] }], selection: [{ type: i0.Input, args: [{ isSignal: true, alias: "selection", required: false }] }, { type: i0.Output, args: ["selectionChange"] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], hiddenColumns: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenColumns", required: false }] }], minTableWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTableWidth", required: false }] }], columnFilters: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnFilters", required: false }] }, { type: i0.Output, args: ["columnFiltersChange"] }], sortField: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortField", required: false }] }, { type: i0.Output, args: ["sortFieldChange"] }], sortOrder: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortOrder", required: false }] }, { type: i0.Output, args: ["sortOrderChange"] }] } });
502
784
 
503
785
  /**
504
786
  * Generated bundle index. Do not edit.