@tekus/design-system 5.41.0 → 5.42.1

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 (35) hide show
  1. package/fesm2022/tekus-design-system-components-carousel.mjs +17 -3
  2. package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -1
  3. package/fesm2022/tekus-design-system-components-checkbox.mjs +2 -2
  4. package/fesm2022/tekus-design-system-components-checkbox.mjs.map +1 -1
  5. package/fesm2022/tekus-design-system-components-color-picker.mjs +172 -75
  6. package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
  7. package/fesm2022/tekus-design-system-components-column-picker.mjs +210 -0
  8. package/fesm2022/tekus-design-system-components-column-picker.mjs.map +1 -0
  9. package/fesm2022/tekus-design-system-components-dropdown.mjs +1 -1
  10. package/fesm2022/tekus-design-system-components-dropdown.mjs.map +1 -1
  11. package/fesm2022/tekus-design-system-components-icon.mjs +10 -0
  12. package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
  13. package/fesm2022/tekus-design-system-components-link-group.mjs +74 -0
  14. package/fesm2022/tekus-design-system-components-link-group.mjs.map +1 -0
  15. package/fesm2022/tekus-design-system-components-panel.mjs +1 -1
  16. package/fesm2022/tekus-design-system-components-panel.mjs.map +1 -1
  17. package/fesm2022/tekus-design-system-components-skeleton.mjs +79 -0
  18. package/fesm2022/tekus-design-system-components-skeleton.mjs.map +1 -0
  19. package/fesm2022/tekus-design-system-components-table.mjs +234 -11
  20. package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
  21. package/fesm2022/tekus-design-system-components-tabs.mjs +1 -1
  22. package/fesm2022/tekus-design-system-components-tabs.mjs.map +1 -1
  23. package/fesm2022/tekus-design-system-components-toolbar.mjs +33 -3
  24. package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
  25. package/fesm2022/tekus-design-system-components-tooltip.mjs +16 -3
  26. package/fesm2022/tekus-design-system-components-tooltip.mjs.map +1 -1
  27. package/package.json +13 -1
  28. package/types/tekus-design-system-components-carousel.d.ts +8 -1
  29. package/types/tekus-design-system-components-color-picker.d.ts +63 -10
  30. package/types/tekus-design-system-components-column-picker.d.ts +116 -0
  31. package/types/tekus-design-system-components-link-group.d.ts +119 -0
  32. package/types/tekus-design-system-components-skeleton.d.ts +68 -0
  33. package/types/tekus-design-system-components-table.d.ts +186 -10
  34. package/types/tekus-design-system-components-toolbar.d.ts +37 -2
  35. package/types/tekus-design-system-components-tooltip.d.ts +12 -1
@@ -1,5 +1,5 @@
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
3
  import { NgTemplateOutlet } from '@angular/common';
4
4
  import * as i1 from 'primeng/table';
5
5
  import { TableModule } from 'primeng/table';
@@ -15,8 +15,11 @@ import { CounterComponent } from '@tekus/design-system/components/counter';
15
15
  import { BadgeComponent } from '@tekus/design-system/components/badge';
16
16
  import { ToggleComponent } from '@tekus/design-system/components/toggle';
17
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';
18
20
  import * as i2 from 'primeng/api';
19
21
 
22
+ const isObject = (value) => typeof value === 'object' && value !== null;
20
23
  /**
21
24
  * @component TableComponent
22
25
  * @description
@@ -31,10 +34,11 @@ import * as i2 from 'primeng/api';
31
34
  class TableComponent {
32
35
  constructor() {
33
36
  /**
34
- * @property {InputSignal<T[]>} data
37
+ * @property {ModelSignal<T[]>} data
35
38
  * @description
36
39
  * Array of data objects to display in the table rows.
37
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.
38
42
  *
39
43
  * @default []
40
44
  *
@@ -44,7 +48,7 @@ class TableComponent {
44
48
  * { id: 2, name: 'Jane', status: 'inactive' }
45
49
  * ]"
46
50
  */
47
- this.data = input([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
51
+ this.data = model([], ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
48
52
  /**
49
53
  * @property {viewChild} tableRef
50
54
  * @description
@@ -68,6 +72,46 @@ class TableComponent {
68
72
  * ]"
69
73
  */
70
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();
71
115
  /**
72
116
  * @property {InputSignal<'single' | 'multiple' | undefined>} selectionMode
73
117
  * @description
@@ -86,6 +130,30 @@ class TableComponent {
86
130
  * Property name to uniquely identify a row.
87
131
  */
88
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 */ []));
89
157
  /**
90
158
  * @property {InputSignal<string | null>} minTableWidth
91
159
  * @description
@@ -97,8 +165,24 @@ class TableComponent {
97
165
  */
98
166
  this.minTableWidth = input('60rem', ...(ngDevMode ? [{ debugName: "minTableWidth" }] : /* istanbul ignore next */ []));
99
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 */ []));
100
178
  this.internalData = signal([], ...(ngDevMode ? [{ debugName: "internalData" }] : /* istanbul ignore next */ []));
101
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);
102
186
  /** Tracks which column's filter overlay is currently open */
103
187
  this.activeFilterColumn = signal(null, ...(ngDevMode ? [{ debugName: "activeFilterColumn" }] : /* istanbul ignore next */ []));
104
188
  /** Stores the selected filter value per column field (null = no filter) */
@@ -138,6 +222,16 @@ class TableComponent {
138
222
  const allSelected = this.isAllSelected();
139
223
  return !allSelected && selected.length > 0;
140
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 */ []));
141
235
  this.actionGroupCache = new Map();
142
236
  /**
143
237
  * @effect data → initialData sync
@@ -212,6 +306,61 @@ class TableComponent {
212
306
  updateSelection(value) {
213
307
  this.selection.set([...value]);
214
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
+ }
215
364
  getActionGroup(actions, row) {
216
365
  if (!actions)
217
366
  return [];
@@ -526,18 +675,90 @@ class TableComponent {
526
675
  /**
527
676
  * @method onImageError
528
677
  * @description
529
- * 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.
530
680
  * Called from the template's (error) binding on image-type columns.
531
681
  * @param event {Event} - The native error event from the <img> element.
532
- * @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.
684
+ */
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.
533
700
  */
534
- onImageError(event, fallback) {
535
- if (fallback) {
536
- event.target.src = fallback;
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);
537
758
  }
538
759
  }
539
760
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
540
- 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 }, 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: { 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 <!-- 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 <!-- 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 <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 <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 </ng-template>\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}", 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}.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__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"] }, { 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"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], 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 }); }
541
762
  }
542
763
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: TableComponent, decorators: [{
543
764
  type: Component,
@@ -555,9 +776,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
555
776
  BadgeComponent,
556
777
  ToggleComponent,
557
778
  TooltipComponent,
779
+ LinkGroupComponent,
780
+ SkeletonComponent,
558
781
  NgTemplateOutlet,
559
- ], 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 <!-- 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 <!-- 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 <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 <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 </ng-template>\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}", 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}.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__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"] }]
560
- }], 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 }] }], 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"] }] } });
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"] }] } });
561
784
 
562
785
  /**
563
786
  * Generated bundle index. Do not edit.