@tailng-ui/primitives 0.41.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +2 -2
  2. package/src/lib/layout/index.d.ts +1 -0
  3. package/src/lib/layout/index.d.ts.map +1 -1
  4. package/src/lib/layout/index.js +1 -0
  5. package/src/lib/layout/index.js.map +1 -1
  6. package/src/lib/layout/table/__tests__/tng-table.test-harness.d.ts +300 -0
  7. package/src/lib/layout/table/__tests__/tng-table.test-harness.d.ts.map +1 -0
  8. package/src/lib/layout/table/__tests__/tng-table.test-harness.js +2492 -0
  9. package/src/lib/layout/table/__tests__/tng-table.test-harness.js.map +1 -0
  10. package/src/lib/layout/table/index.d.ts +6 -0
  11. package/src/lib/layout/table/index.d.ts.map +1 -0
  12. package/src/lib/layout/table/index.js +6 -0
  13. package/src/lib/layout/table/index.js.map +1 -0
  14. package/src/lib/layout/table/tng-table-render.d.ts +175 -0
  15. package/src/lib/layout/table/tng-table-render.d.ts.map +1 -0
  16. package/src/lib/layout/table/tng-table-render.js +304 -0
  17. package/src/lib/layout/table/tng-table-render.js.map +1 -0
  18. package/src/lib/layout/table/tng-table-sizing.d.ts +75 -0
  19. package/src/lib/layout/table/tng-table-sizing.d.ts.map +1 -0
  20. package/src/lib/layout/table/tng-table-sizing.js +361 -0
  21. package/src/lib/layout/table/tng-table-sizing.js.map +1 -0
  22. package/src/lib/layout/table/tng-table-sort.d.ts +53 -0
  23. package/src/lib/layout/table/tng-table-sort.d.ts.map +1 -0
  24. package/src/lib/layout/table/tng-table-sort.js +167 -0
  25. package/src/lib/layout/table/tng-table-sort.js.map +1 -0
  26. package/src/lib/layout/table/tng-table-virtual.d.ts +55 -0
  27. package/src/lib/layout/table/tng-table-virtual.d.ts.map +1 -0
  28. package/src/lib/layout/table/tng-table-virtual.js +250 -0
  29. package/src/lib/layout/table/tng-table-virtual.js.map +1 -0
  30. package/src/lib/layout/table/tng-table.d.ts +362 -0
  31. package/src/lib/layout/table/tng-table.d.ts.map +1 -0
  32. package/src/lib/layout/table/tng-table.js +1490 -0
  33. package/src/lib/layout/table/tng-table.js.map +1 -0
@@ -0,0 +1,1490 @@
1
+ import { Directive, HostBinding, HostListener, Input, booleanAttribute, contentChildren, ElementRef, forwardRef, inject, input, output, } from '@angular/core';
2
+ import { createTngRowExpansionController, createTngRowSelectionController, resolveGridNavigationKeyAction, resolveNavigableGridCell, } from '@tailng-ui/cdk';
3
+ import * as i0 from "@angular/core";
4
+ const tngTableInteractiveTargetSelector = [
5
+ 'a[href]',
6
+ 'button',
7
+ 'input',
8
+ 'label',
9
+ 'select',
10
+ 'summary',
11
+ 'textarea',
12
+ '[contenteditable=""]',
13
+ '[contenteditable="plaintext-only"]',
14
+ '[contenteditable="true"]',
15
+ '[data-tng-table-interactive]',
16
+ '[role="button"]',
17
+ '[role="checkbox"]',
18
+ '[role="combobox"]',
19
+ '[role="link"]',
20
+ '[role="listbox"]',
21
+ '[role="menuitem"]',
22
+ '[role="option"]',
23
+ '[role="radio"]',
24
+ '[role="switch"]',
25
+ '[role="tab"]',
26
+ '[role="textbox"]',
27
+ ].join(',');
28
+ function createTngTableCellKey(position) {
29
+ return `${position.row}:${position.col}`;
30
+ }
31
+ function compareTngTableCellPositions(a, b) {
32
+ if (a.row !== b.row) {
33
+ return a.row - b.row;
34
+ }
35
+ return a.col - b.col;
36
+ }
37
+ function isMovementActionType(actionType) {
38
+ return actionType !== 'activate' && actionType !== 'exit';
39
+ }
40
+ function resolveTngTableCellPosition(element) {
41
+ if (element.cellIndex < 0) {
42
+ return null;
43
+ }
44
+ const rowElement = element.parentElement;
45
+ if (!(rowElement instanceof HTMLTableRowElement) || rowElement.rowIndex < 0) {
46
+ return null;
47
+ }
48
+ return Object.freeze({
49
+ col: element.cellIndex,
50
+ row: rowElement.rowIndex,
51
+ });
52
+ }
53
+ function isInsideContainer(container, value) {
54
+ return value instanceof Node && container.contains(value);
55
+ }
56
+ function isFocusVisibleElement(value) {
57
+ return value.matches(':focus-visible');
58
+ }
59
+ function hasTableKeyboardModifiers(event) {
60
+ return event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
61
+ }
62
+ function hasInteractiveEventTarget(container, target) {
63
+ if (!(target instanceof Element)) {
64
+ return false;
65
+ }
66
+ const interactiveTarget = target.closest(tngTableInteractiveTargetSelector);
67
+ return interactiveTarget !== null && interactiveTarget !== container && container.contains(interactiveTarget);
68
+ }
69
+ function resolveTngTablePageDirection(key) {
70
+ if (key === 'PageDown') {
71
+ return 'forward';
72
+ }
73
+ if (key === 'PageUp') {
74
+ return 'backward';
75
+ }
76
+ return null;
77
+ }
78
+ function normalizeCssLength(value) {
79
+ if (typeof value === 'number' && Number.isFinite(value)) {
80
+ return `${value}px`;
81
+ }
82
+ if (typeof value !== 'string') {
83
+ return null;
84
+ }
85
+ const trimmed = value.trim();
86
+ return trimmed.length > 0 ? trimmed : null;
87
+ }
88
+ function normalizeTableLayoutMode(value) {
89
+ return value === 'fixed' ? 'fixed' : 'auto';
90
+ }
91
+ function normalizeTableScrollAxis(value) {
92
+ if (value === 'both' || value === 'y') {
93
+ return value;
94
+ }
95
+ return 'x';
96
+ }
97
+ function normalizeTableStickySide(value) {
98
+ return value === 'start' || value === 'end' ? value : null;
99
+ }
100
+ function resolveStickyPhysicalSide(side, direction) {
101
+ if (side === 'start') {
102
+ return direction === 'rtl' ? 'right' : 'left';
103
+ }
104
+ return direction === 'rtl' ? 'left' : 'right';
105
+ }
106
+ function normalizeTableDirection(value) {
107
+ if (value === 'ltr' || value === 'rtl') {
108
+ return value;
109
+ }
110
+ return null;
111
+ }
112
+ export function resolveTngTableEmptyState(items, loading) {
113
+ if (loading || items === null || items === undefined) {
114
+ return false;
115
+ }
116
+ return items.length === 0;
117
+ }
118
+ function normalizeExpansionMode(value) {
119
+ return value === 'single' ? 'single' : 'multiple';
120
+ }
121
+ function normalizeOptionalString(value) {
122
+ if (typeof value !== 'string') {
123
+ return null;
124
+ }
125
+ const trimmed = value.trim();
126
+ return trimmed.length > 0 ? trimmed : null;
127
+ }
128
+ function normalizeOptionalStringArray(value) {
129
+ return Array.isArray(value)
130
+ ? value
131
+ .filter((item) => typeof item === 'string')
132
+ .map((item) => item.trim())
133
+ .filter((item) => item.length > 0)
134
+ : [];
135
+ }
136
+ function normalizeSelectionMode(value) {
137
+ return value === 'multiple' ? 'multiple' : 'single';
138
+ }
139
+ function normalizeBooleanOrNull(value) {
140
+ if (value === undefined || value === null) {
141
+ return null;
142
+ }
143
+ return booleanAttribute(value);
144
+ }
145
+ export class TngTableHeader {
146
+ sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : {}), alias: 'tngTableHeaderSticky',
147
+ transform: booleanAttribute });
148
+ stickyOffset = input(null, { ...(ngDevMode ? { debugName: "stickyOffset" } : {}), alias: 'tngTableHeaderStickyOffset',
149
+ transform: normalizeCssLength });
150
+ dataSlot = 'table-header';
151
+ get dataStickyAttr() {
152
+ return this.isSticky() ? '' : null;
153
+ }
154
+ getStickyInset() {
155
+ return this.stickyOffset() ?? '0px';
156
+ }
157
+ isSticky() {
158
+ return this.sticky();
159
+ }
160
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
161
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableHeader, isStandalone: true, selector: "thead[tngTableHeader]", inputs: { sticky: { classPropertyName: "sticky", publicName: "tngTableHeaderSticky", isSignal: true, isRequired: false, transformFunction: null }, stickyOffset: { classPropertyName: "stickyOffset", publicName: "tngTableHeaderStickyOffset", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-slot": "this.dataSlot", "attr.data-sticky": "this.dataStickyAttr" } }, exportAs: ["tngTableHeader"], ngImport: i0 });
162
+ }
163
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableHeader, decorators: [{
164
+ type: Directive,
165
+ args: [{
166
+ selector: 'thead[tngTableHeader]',
167
+ exportAs: 'tngTableHeader',
168
+ }]
169
+ }], propDecorators: { sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableHeaderSticky", required: false }] }], stickyOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableHeaderStickyOffset", required: false }] }], dataSlot: [{
170
+ type: HostBinding,
171
+ args: ['attr.data-slot']
172
+ }], dataStickyAttr: [{
173
+ type: HostBinding,
174
+ args: ['attr.data-sticky']
175
+ }] } });
176
+ export class TngTableBody {
177
+ dataSlot = 'table-body';
178
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableBody, deps: [], target: i0.ɵɵFactoryTarget.Directive });
179
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTableBody, isStandalone: true, selector: "tbody[tngTableBody]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableBody"], ngImport: i0 });
180
+ }
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableBody, decorators: [{
182
+ type: Directive,
183
+ args: [{
184
+ selector: 'tbody[tngTableBody]',
185
+ exportAs: 'tngTableBody',
186
+ }]
187
+ }], propDecorators: { dataSlot: [{
188
+ type: HostBinding,
189
+ args: ['attr.data-slot']
190
+ }] } });
191
+ export class TngTableFooter {
192
+ sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : {}), alias: 'tngTableFooterSticky',
193
+ transform: booleanAttribute });
194
+ stickyOffset = input(null, { ...(ngDevMode ? { debugName: "stickyOffset" } : {}), alias: 'tngTableFooterStickyOffset',
195
+ transform: normalizeCssLength });
196
+ dataSlot = 'table-footer';
197
+ get dataStickyAttr() {
198
+ return this.isSticky() ? '' : null;
199
+ }
200
+ getStickyInset() {
201
+ return this.stickyOffset() ?? '0px';
202
+ }
203
+ isSticky() {
204
+ return this.sticky();
205
+ }
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
207
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableFooter, isStandalone: true, selector: "tfoot[tngTableFooter]", inputs: { sticky: { classPropertyName: "sticky", publicName: "tngTableFooterSticky", isSignal: true, isRequired: false, transformFunction: null }, stickyOffset: { classPropertyName: "stickyOffset", publicName: "tngTableFooterStickyOffset", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-slot": "this.dataSlot", "attr.data-sticky": "this.dataStickyAttr" } }, exportAs: ["tngTableFooter"], ngImport: i0 });
208
+ }
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableFooter, decorators: [{
210
+ type: Directive,
211
+ args: [{
212
+ selector: 'tfoot[tngTableFooter]',
213
+ exportAs: 'tngTableFooter',
214
+ }]
215
+ }], propDecorators: { sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableFooterSticky", required: false }] }], stickyOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableFooterStickyOffset", required: false }] }], dataSlot: [{
216
+ type: HostBinding,
217
+ args: ['attr.data-slot']
218
+ }], dataStickyAttr: [{
219
+ type: HostBinding,
220
+ args: ['attr.data-sticky']
221
+ }] } });
222
+ export class TngTableScrollContainer {
223
+ axis = input('x', { ...(ngDevMode ? { debugName: "axis" } : {}), alias: 'tngTableScrollAxis',
224
+ transform: normalizeTableScrollAxis });
225
+ dir = input(null, { ...(ngDevMode ? { debugName: "dir" } : {}), alias: 'dir',
226
+ transform: normalizeTableDirection });
227
+ dataSlot = 'table-scroll-container';
228
+ get dirAttr() {
229
+ return this.dir();
230
+ }
231
+ get dataOverflowAxisAttr() {
232
+ return this.axis();
233
+ }
234
+ display = 'block';
235
+ maxWidth = '100%';
236
+ get directionStyleAttr() {
237
+ return this.dir();
238
+ }
239
+ get overflowXAttr() {
240
+ return this.axis() === 'x' || this.axis() === 'both' ? 'auto' : 'hidden';
241
+ }
242
+ get overflowYAttr() {
243
+ return this.axis() === 'y' || this.axis() === 'both' ? 'auto' : 'hidden';
244
+ }
245
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableScrollContainer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
246
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableScrollContainer, isStandalone: true, selector: "[tngTableScrollContainer]", inputs: { axis: { classPropertyName: "axis", publicName: "tngTableScrollAxis", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-slot": "this.dataSlot", "attr.dir": "this.dirAttr", "attr.data-overflow-axis": "this.dataOverflowAxisAttr", "style.display": "this.display", "style.max-width": "this.maxWidth", "style.direction": "this.directionStyleAttr", "style.overflow-x": "this.overflowXAttr", "style.overflow-y": "this.overflowYAttr" } }, exportAs: ["tngTableScrollContainer"], ngImport: i0 });
247
+ }
248
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableScrollContainer, decorators: [{
249
+ type: Directive,
250
+ args: [{
251
+ selector: '[tngTableScrollContainer]',
252
+ exportAs: 'tngTableScrollContainer',
253
+ }]
254
+ }], propDecorators: { axis: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableScrollAxis", required: false }] }], dir: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], dataSlot: [{
255
+ type: HostBinding,
256
+ args: ['attr.data-slot']
257
+ }], dirAttr: [{
258
+ type: HostBinding,
259
+ args: ['attr.dir']
260
+ }], dataOverflowAxisAttr: [{
261
+ type: HostBinding,
262
+ args: ['attr.data-overflow-axis']
263
+ }], display: [{
264
+ type: HostBinding,
265
+ args: ['style.display']
266
+ }], maxWidth: [{
267
+ type: HostBinding,
268
+ args: ['style.max-width']
269
+ }], directionStyleAttr: [{
270
+ type: HostBinding,
271
+ args: ['style.direction']
272
+ }], overflowXAttr: [{
273
+ type: HostBinding,
274
+ args: ['style.overflow-x']
275
+ }], overflowYAttr: [{
276
+ type: HostBinding,
277
+ args: ['style.overflow-y']
278
+ }] } });
279
+ export class TngTableSelection {
280
+ rows = contentChildren(forwardRef(() => TngTableRow), {
281
+ descendants: true,
282
+ });
283
+ uncontrolledAnchorId = null;
284
+ uncontrolledSelectedIds = [];
285
+ mode = input('single', { ...(ngDevMode ? { debugName: "mode" } : {}), alias: 'tngTableSelectionMode',
286
+ transform: normalizeSelectionMode });
287
+ selectedIds = input(undefined, { ...(ngDevMode ? { debugName: "selectedIds" } : {}), alias: 'tngTableSelectedIds' });
288
+ selectionChange = output();
289
+ dataSelectable = '';
290
+ clear(trigger = 'programmatic') {
291
+ return this.commit(this.createController().clear(), null, trigger);
292
+ }
293
+ isSelected(rowId) {
294
+ return this.createController().isSelected(rowId);
295
+ }
296
+ replace(rowId, trigger = 'programmatic') {
297
+ return this.commit(this.createController().replace(rowId), rowId, trigger);
298
+ }
299
+ selectAll(rowIds, trigger = 'programmatic') {
300
+ return this.commit(this.createController().selectAll(rowIds), rowIds[0] ?? null, trigger);
301
+ }
302
+ toggle(rowId, trigger = 'programmatic') {
303
+ return this.commit(this.createController().toggle(rowId), rowId, trigger);
304
+ }
305
+ toggleFromPointer(row, event) {
306
+ const rowId = row.rowId();
307
+ if (rowId === null || row.isDisabled()) {
308
+ return;
309
+ }
310
+ const controller = this.createController();
311
+ const nextState = this.resolvePointerSelectionState(controller, rowId, event);
312
+ this.commit(nextState, rowId, 'pointer');
313
+ }
314
+ commit(nextState, changedId, trigger) {
315
+ this.uncontrolledAnchorId = nextState.anchorId;
316
+ if (this.selectedIds() === undefined) {
317
+ this.uncontrolledSelectedIds = nextState.selectedIds;
318
+ }
319
+ this.selectionChange.emit(Object.freeze({
320
+ anchorId: nextState.anchorId,
321
+ changedId,
322
+ selectedIds: nextState.selectedIds,
323
+ trigger,
324
+ }));
325
+ return nextState;
326
+ }
327
+ createController() {
328
+ return createTngRowSelectionController({
329
+ disabledIds: this.getDisabledRowIds(),
330
+ initialAnchorId: this.getAnchorId(),
331
+ initialSelectedIds: this.getCurrentSelectedIds(),
332
+ mode: this.mode(),
333
+ });
334
+ }
335
+ getAnchorId() {
336
+ const selectedIds = this.getCurrentSelectedIds();
337
+ const lastSelectedId = selectedIds.length > 0 ? selectedIds[selectedIds.length - 1] ?? null : null;
338
+ return this.uncontrolledAnchorId !== null && selectedIds.includes(this.uncontrolledAnchorId)
339
+ ? this.uncontrolledAnchorId
340
+ : lastSelectedId;
341
+ }
342
+ getCurrentSelectedIds() {
343
+ const controlledSelectedIds = this.selectedIds();
344
+ return controlledSelectedIds === undefined
345
+ ? this.uncontrolledSelectedIds
346
+ : normalizeOptionalStringArray(controlledSelectedIds);
347
+ }
348
+ getDisabledRowIds() {
349
+ return this.rows()
350
+ .filter((row) => row.isDisabled())
351
+ .map((row) => row.rowId())
352
+ .filter((rowId) => rowId !== null);
353
+ }
354
+ getOrderedRowIds() {
355
+ return this.rows()
356
+ .map((row) => row.rowId())
357
+ .filter((rowId) => rowId !== null);
358
+ }
359
+ resolvePointerSelectionState(controller, rowId, event) {
360
+ if (this.mode() !== 'multiple') {
361
+ return controller.replace(rowId);
362
+ }
363
+ if (event.shiftKey) {
364
+ return controller.selectRange(controller.getState().anchorId ?? rowId, rowId, this.getOrderedRowIds());
365
+ }
366
+ if (event.ctrlKey || event.metaKey) {
367
+ return controller.toggle(rowId);
368
+ }
369
+ return controller.replace(rowId);
370
+ }
371
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableSelection, deps: [], target: i0.ɵɵFactoryTarget.Directive });
372
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.1.1", type: TngTableSelection, isStandalone: true, selector: "table[tngTable][tngTableSelection]", inputs: { mode: { classPropertyName: "mode", publicName: "tngTableSelectionMode", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "tngTableSelectedIds", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, host: { properties: { "attr.data-selectable": "this.dataSelectable" } }, queries: [{ propertyName: "rows", predicate: i0.forwardRef(() => TngTableRow), descendants: true, isSignal: true }], exportAs: ["tngTableSelection"], ngImport: i0 });
373
+ }
374
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableSelection, decorators: [{
375
+ type: Directive,
376
+ args: [{
377
+ selector: 'table[tngTable][tngTableSelection]',
378
+ exportAs: 'tngTableSelection',
379
+ }]
380
+ }], propDecorators: { rows: [{ type: i0.ContentChildren, args: [forwardRef(() => TngTableRow), { ...{
381
+ descendants: true,
382
+ }, isSignal: true }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableSelectionMode", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableSelectedIds", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], dataSelectable: [{
383
+ type: HostBinding,
384
+ args: ['attr.data-selectable']
385
+ }] } });
386
+ export class TngTableExpansion {
387
+ uncontrolledExpandedIds = [];
388
+ expandedIds = input(undefined, { ...(ngDevMode ? { debugName: "expandedIds" } : {}), alias: 'tngTableExpandedIds' });
389
+ mode = input('multiple', { ...(ngDevMode ? { debugName: "mode" } : {}), alias: 'tngTableExpansionMode',
390
+ transform: normalizeExpansionMode });
391
+ expansionChange = output();
392
+ dataExpandable = '';
393
+ clear(trigger = 'programmatic') {
394
+ const nextState = this.createController().clear();
395
+ return this.commit(nextState, null, trigger);
396
+ }
397
+ isExpanded(rowId) {
398
+ return this.createController().isExpanded(rowId);
399
+ }
400
+ toggle(rowId, trigger = 'programmatic') {
401
+ const nextState = this.createController().toggle(rowId);
402
+ return this.commit(nextState, rowId, trigger);
403
+ }
404
+ commit(nextState, rowId, trigger) {
405
+ if (this.expandedIds() === undefined) {
406
+ this.uncontrolledExpandedIds = nextState.expandedIds;
407
+ }
408
+ if (rowId !== null) {
409
+ this.expansionChange.emit(Object.freeze({
410
+ expanded: nextState.expandedIds.includes(rowId),
411
+ expandedIds: nextState.expandedIds,
412
+ rowId,
413
+ trigger,
414
+ }));
415
+ }
416
+ return nextState;
417
+ }
418
+ createController() {
419
+ return createTngRowExpansionController({
420
+ initialExpandedIds: this.getCurrentExpandedIds(),
421
+ mode: this.mode(),
422
+ });
423
+ }
424
+ getCurrentExpandedIds() {
425
+ const controlledExpandedIds = this.expandedIds();
426
+ return controlledExpandedIds === undefined
427
+ ? this.uncontrolledExpandedIds
428
+ : normalizeOptionalStringArray(controlledExpandedIds);
429
+ }
430
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableExpansion, deps: [], target: i0.ɵɵFactoryTarget.Directive });
431
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableExpansion, isStandalone: true, selector: "table[tngTable][tngTableExpansion]", inputs: { expandedIds: { classPropertyName: "expandedIds", publicName: "tngTableExpandedIds", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "tngTableExpansionMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expansionChange: "expansionChange" }, host: { properties: { "attr.data-expandable": "this.dataExpandable" } }, exportAs: ["tngTableExpansion"], ngImport: i0 });
432
+ }
433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableExpansion, decorators: [{
434
+ type: Directive,
435
+ args: [{
436
+ selector: 'table[tngTable][tngTableExpansion]',
437
+ exportAs: 'tngTableExpansion',
438
+ }]
439
+ }], propDecorators: { expandedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableExpandedIds", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableExpansionMode", required: false }] }], expansionChange: [{ type: i0.Output, args: ["expansionChange"] }], dataExpandable: [{
440
+ type: HostBinding,
441
+ args: ['attr.data-expandable']
442
+ }] } });
443
+ export class TngTableRow {
444
+ expansion = inject(forwardRef(() => TngTableExpansion), {
445
+ optional: true,
446
+ });
447
+ hostRef = inject(ElementRef);
448
+ selection = inject(forwardRef(() => TngTableSelection), {
449
+ optional: true,
450
+ });
451
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'tngTableRowDisabled',
452
+ transform: booleanAttribute });
453
+ expanded = input(null, { ...(ngDevMode ? { debugName: "expanded" } : {}), alias: 'tngTableRowExpanded',
454
+ transform: normalizeBooleanOrNull });
455
+ rowId = input(null, { ...(ngDevMode ? { debugName: "rowId" } : {}), alias: 'tngTableRowId',
456
+ transform: normalizeOptionalString });
457
+ selected = input(null, { ...(ngDevMode ? { debugName: "selected" } : {}), alias: 'tngTableRowSelected',
458
+ transform: normalizeBooleanOrNull });
459
+ rowClick = output();
460
+ rowContextMenu = output();
461
+ dataSlot = 'table-row';
462
+ get ariaDisabledAttr() {
463
+ return this.isDisabled() ? 'true' : null;
464
+ }
465
+ get ariaSelectedAttr() {
466
+ if (this.selected() === null && this.selection === null) {
467
+ return null;
468
+ }
469
+ return this.isSelected() ? 'true' : 'false';
470
+ }
471
+ get dataDisabledAttr() {
472
+ return this.isDisabled() ? '' : null;
473
+ }
474
+ get dataExpandedAttr() {
475
+ return this.isExpanded() ? '' : null;
476
+ }
477
+ get dataRowIdAttr() {
478
+ return this.rowId();
479
+ }
480
+ get dataSelectedAttr() {
481
+ return this.isSelected() ? '' : null;
482
+ }
483
+ isDisabled() {
484
+ return this.disabled();
485
+ }
486
+ isExpanded() {
487
+ const expanded = this.expanded();
488
+ if (expanded !== null) {
489
+ return expanded;
490
+ }
491
+ const rowId = this.rowId();
492
+ return rowId !== null && this.expansion?.isExpanded(rowId) === true;
493
+ }
494
+ isSelected() {
495
+ const selected = this.selected();
496
+ if (selected !== null) {
497
+ return selected;
498
+ }
499
+ const rowId = this.rowId();
500
+ return rowId !== null && this.selection?.isSelected(rowId) === true;
501
+ }
502
+ onClick(event) {
503
+ if (this.isDisabled()
504
+ || event.defaultPrevented
505
+ || hasInteractiveEventTarget(this.hostRef.nativeElement, event.target)) {
506
+ return;
507
+ }
508
+ this.selection?.toggleFromPointer(this, event);
509
+ this.rowClick.emit(Object.freeze({
510
+ originalEvent: event,
511
+ rowId: this.rowId(),
512
+ }));
513
+ }
514
+ onContextMenu(event) {
515
+ if (this.isDisabled()) {
516
+ return;
517
+ }
518
+ this.rowContextMenu.emit(Object.freeze({
519
+ originalEvent: event,
520
+ rowId: this.rowId(),
521
+ }));
522
+ }
523
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableRow, deps: [], target: i0.ɵɵFactoryTarget.Directive });
524
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableRow, isStandalone: true, selector: "tr[tngTableRow]", inputs: { disabled: { classPropertyName: "disabled", publicName: "tngTableRowDisabled", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "tngTableRowExpanded", isSignal: true, isRequired: false, transformFunction: null }, rowId: { classPropertyName: "rowId", publicName: "tngTableRowId", isSignal: true, isRequired: false, transformFunction: null }, selected: { classPropertyName: "selected", publicName: "tngTableRowSelected", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { rowClick: "rowClick", rowContextMenu: "rowContextMenu" }, host: { listeners: { "click": "onClick($event)", "contextmenu": "onContextMenu($event)" }, properties: { "attr.data-slot": "this.dataSlot", "attr.aria-disabled": "this.ariaDisabledAttr", "attr.aria-selected": "this.ariaSelectedAttr", "attr.data-disabled": "this.dataDisabledAttr", "attr.data-expanded": "this.dataExpandedAttr", "attr.data-row-id": "this.dataRowIdAttr", "attr.data-selected": "this.dataSelectedAttr" } }, exportAs: ["tngTableRow"], ngImport: i0 });
525
+ }
526
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableRow, decorators: [{
527
+ type: Directive,
528
+ args: [{
529
+ selector: 'tr[tngTableRow]',
530
+ exportAs: 'tngTableRow',
531
+ }]
532
+ }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableRowDisabled", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableRowExpanded", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableRowId", required: false }] }], selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableRowSelected", required: false }] }], rowClick: [{ type: i0.Output, args: ["rowClick"] }], rowContextMenu: [{ type: i0.Output, args: ["rowContextMenu"] }], dataSlot: [{
533
+ type: HostBinding,
534
+ args: ['attr.data-slot']
535
+ }], ariaDisabledAttr: [{
536
+ type: HostBinding,
537
+ args: ['attr.aria-disabled']
538
+ }], ariaSelectedAttr: [{
539
+ type: HostBinding,
540
+ args: ['attr.aria-selected']
541
+ }], dataDisabledAttr: [{
542
+ type: HostBinding,
543
+ args: ['attr.data-disabled']
544
+ }], dataExpandedAttr: [{
545
+ type: HostBinding,
546
+ args: ['attr.data-expanded']
547
+ }], dataRowIdAttr: [{
548
+ type: HostBinding,
549
+ args: ['attr.data-row-id']
550
+ }], dataSelectedAttr: [{
551
+ type: HostBinding,
552
+ args: ['attr.data-selected']
553
+ }], onClick: [{
554
+ type: HostListener,
555
+ args: ['click', ['$event']]
556
+ }], onContextMenu: [{
557
+ type: HostListener,
558
+ args: ['contextmenu', ['$event']]
559
+ }] } });
560
+ export class TngTableCell {
561
+ footer = inject(TngTableFooter, {
562
+ optional: true,
563
+ });
564
+ hostRef = inject(ElementRef);
565
+ row = inject(TngTableRow, {
566
+ optional: true,
567
+ });
568
+ table = inject(forwardRef(() => TngTable));
569
+ cellClick = output();
570
+ columnId = input(null, { ...(ngDevMode ? { debugName: "columnId" } : {}), alias: 'tngTableColumnId',
571
+ transform: normalizeOptionalString });
572
+ headers = input(null, { ...(ngDevMode ? { debugName: "headers" } : {}), alias: 'tngTableHeaders',
573
+ transform: normalizeOptionalString });
574
+ stickyColumn = input(null, { ...(ngDevMode ? { debugName: "stickyColumn" } : {}), alias: 'tngTableStickyColumn',
575
+ transform: normalizeTableStickySide });
576
+ stickyOffset = input(null, { ...(ngDevMode ? { debugName: "stickyOffset" } : {}), alias: 'tngTableStickyOffset',
577
+ transform: normalizeCssLength });
578
+ truncate = input(false, { ...(ngDevMode ? { debugName: "truncate" } : {}), alias: 'tngTableTruncate',
579
+ transform: booleanAttribute });
580
+ dataSlot = 'table-cell';
581
+ get dataColumnIdAttr() {
582
+ return this.columnId();
583
+ }
584
+ get dataRowIdAttr() {
585
+ return this.row?.rowId() ?? null;
586
+ }
587
+ get headersAttr() {
588
+ return this.headers();
589
+ }
590
+ get dataStickyAttr() {
591
+ return this.isSectionSticky() || this.getStickySide() !== null ? '' : null;
592
+ }
593
+ get dataStickyFooterAttr() {
594
+ return this.footer?.isSticky() === true ? '' : null;
595
+ }
596
+ get dataStickySideAttr() {
597
+ return this.getStickySide();
598
+ }
599
+ get dataTruncateAttr() {
600
+ return this.truncate() ? '' : null;
601
+ }
602
+ get tabIndexAttr() {
603
+ return this.table.getCellTabIndex(this);
604
+ }
605
+ get bottomAttr() {
606
+ return this.footer?.isSticky() === true ? this.footer.getStickyInset() : null;
607
+ }
608
+ get dataFocusedAttr() {
609
+ return this.table.isCellFocused(this) ? '' : null;
610
+ }
611
+ get dataFocusVisibleAttr() {
612
+ return this.table.isCellFocusVisible(this) ? '' : null;
613
+ }
614
+ get leftAttr() {
615
+ return this.table.getCellStickyInset(this, 'left');
616
+ }
617
+ get overflowAttr() {
618
+ return this.truncate() ? 'hidden' : null;
619
+ }
620
+ get positionAttr() {
621
+ return this.table.getCellStickyPosition(this);
622
+ }
623
+ get rightAttr() {
624
+ return this.table.getCellStickyInset(this, 'right');
625
+ }
626
+ get textOverflowAttr() {
627
+ return this.truncate() ? 'ellipsis' : null;
628
+ }
629
+ get whiteSpaceAttr() {
630
+ return this.truncate() ? 'nowrap' : null;
631
+ }
632
+ get zIndexAttr() {
633
+ return this.table.getCellStickyZIndex(this);
634
+ }
635
+ ngOnDestroy() {
636
+ this.table.onCellDestroy(this);
637
+ }
638
+ ngOnInit() {
639
+ this.table.registerCell(this);
640
+ }
641
+ cellKey() {
642
+ const position = this.getCellPosition();
643
+ return position === null ? null : createTngTableCellKey(position);
644
+ }
645
+ focusHost() {
646
+ this.hostRef.nativeElement.focus();
647
+ }
648
+ getCellPosition() {
649
+ return resolveTngTableCellPosition(this.hostRef.nativeElement);
650
+ }
651
+ getHostElement() {
652
+ return this.hostRef.nativeElement;
653
+ }
654
+ getStickyOffset() {
655
+ return this.stickyOffset();
656
+ }
657
+ getStickySide() {
658
+ return this.stickyColumn();
659
+ }
660
+ isDisabled() {
661
+ return this.row?.isDisabled() === true;
662
+ }
663
+ isFocusVisible() {
664
+ return isFocusVisibleElement(this.hostRef.nativeElement);
665
+ }
666
+ isSectionSticky() {
667
+ return this.footer?.isSticky() === true;
668
+ }
669
+ onClick(event) {
670
+ if (this.isDisabled()
671
+ || event.defaultPrevented
672
+ || hasInteractiveEventTarget(this.hostRef.nativeElement, event.target)) {
673
+ return;
674
+ }
675
+ this.cellClick.emit(Object.freeze({
676
+ columnId: this.columnId(),
677
+ originalEvent: event,
678
+ rowId: this.row?.rowId() ?? null,
679
+ }));
680
+ }
681
+ onFocus() {
682
+ this.table.onCellFocused(this);
683
+ }
684
+ onPointerDown() {
685
+ this.table.onCellPointerDown(this);
686
+ }
687
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableCell, deps: [], target: i0.ɵɵFactoryTarget.Directive });
688
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableCell, isStandalone: true, selector: "td[tngTableCell]", inputs: { columnId: { classPropertyName: "columnId", publicName: "tngTableColumnId", isSignal: true, isRequired: false, transformFunction: null }, headers: { classPropertyName: "headers", publicName: "tngTableHeaders", isSignal: true, isRequired: false, transformFunction: null }, stickyColumn: { classPropertyName: "stickyColumn", publicName: "tngTableStickyColumn", isSignal: true, isRequired: false, transformFunction: null }, stickyOffset: { classPropertyName: "stickyOffset", publicName: "tngTableStickyOffset", isSignal: true, isRequired: false, transformFunction: null }, truncate: { classPropertyName: "truncate", publicName: "tngTableTruncate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cellClick: "cellClick" }, host: { listeners: { "click": "onClick($event)", "focus": "onFocus()", "pointerdown": "onPointerDown()" }, properties: { "attr.data-slot": "this.dataSlot", "attr.data-column-id": "this.dataColumnIdAttr", "attr.data-row-id": "this.dataRowIdAttr", "attr.headers": "this.headersAttr", "attr.data-sticky": "this.dataStickyAttr", "attr.data-sticky-footer": "this.dataStickyFooterAttr", "attr.data-sticky-side": "this.dataStickySideAttr", "attr.data-truncate": "this.dataTruncateAttr", "attr.tabindex": "this.tabIndexAttr", "style.bottom": "this.bottomAttr", "attr.data-focused": "this.dataFocusedAttr", "attr.data-focus-visible": "this.dataFocusVisibleAttr", "style.left": "this.leftAttr", "style.overflow": "this.overflowAttr", "style.position": "this.positionAttr", "style.right": "this.rightAttr", "style.text-overflow": "this.textOverflowAttr", "style.white-space": "this.whiteSpaceAttr", "style.z-index": "this.zIndexAttr" } }, exportAs: ["tngTableCell"], ngImport: i0 });
689
+ }
690
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableCell, decorators: [{
691
+ type: Directive,
692
+ args: [{
693
+ selector: 'td[tngTableCell]',
694
+ exportAs: 'tngTableCell',
695
+ }]
696
+ }], propDecorators: { cellClick: [{ type: i0.Output, args: ["cellClick"] }], columnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnId", required: false }] }], headers: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableHeaders", required: false }] }], stickyColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableStickyColumn", required: false }] }], stickyOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableStickyOffset", required: false }] }], truncate: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableTruncate", required: false }] }], dataSlot: [{
697
+ type: HostBinding,
698
+ args: ['attr.data-slot']
699
+ }], dataColumnIdAttr: [{
700
+ type: HostBinding,
701
+ args: ['attr.data-column-id']
702
+ }], dataRowIdAttr: [{
703
+ type: HostBinding,
704
+ args: ['attr.data-row-id']
705
+ }], headersAttr: [{
706
+ type: HostBinding,
707
+ args: ['attr.headers']
708
+ }], dataStickyAttr: [{
709
+ type: HostBinding,
710
+ args: ['attr.data-sticky']
711
+ }], dataStickyFooterAttr: [{
712
+ type: HostBinding,
713
+ args: ['attr.data-sticky-footer']
714
+ }], dataStickySideAttr: [{
715
+ type: HostBinding,
716
+ args: ['attr.data-sticky-side']
717
+ }], dataTruncateAttr: [{
718
+ type: HostBinding,
719
+ args: ['attr.data-truncate']
720
+ }], tabIndexAttr: [{
721
+ type: HostBinding,
722
+ args: ['attr.tabindex']
723
+ }], bottomAttr: [{
724
+ type: HostBinding,
725
+ args: ['style.bottom']
726
+ }], dataFocusedAttr: [{
727
+ type: HostBinding,
728
+ args: ['attr.data-focused']
729
+ }], dataFocusVisibleAttr: [{
730
+ type: HostBinding,
731
+ args: ['attr.data-focus-visible']
732
+ }], leftAttr: [{
733
+ type: HostBinding,
734
+ args: ['style.left']
735
+ }], overflowAttr: [{
736
+ type: HostBinding,
737
+ args: ['style.overflow']
738
+ }], positionAttr: [{
739
+ type: HostBinding,
740
+ args: ['style.position']
741
+ }], rightAttr: [{
742
+ type: HostBinding,
743
+ args: ['style.right']
744
+ }], textOverflowAttr: [{
745
+ type: HostBinding,
746
+ args: ['style.text-overflow']
747
+ }], whiteSpaceAttr: [{
748
+ type: HostBinding,
749
+ args: ['style.white-space']
750
+ }], zIndexAttr: [{
751
+ type: HostBinding,
752
+ args: ['style.z-index']
753
+ }], onClick: [{
754
+ type: HostListener,
755
+ args: ['click', ['$event']]
756
+ }], onFocus: [{
757
+ type: HostListener,
758
+ args: ['focus']
759
+ }], onPointerDown: [{
760
+ type: HostListener,
761
+ args: ['pointerdown']
762
+ }] } });
763
+ export class TngTableHeaderCell {
764
+ header = inject(TngTableHeader, {
765
+ optional: true,
766
+ });
767
+ hostRef = inject(ElementRef);
768
+ table = inject(forwardRef(() => TngTable));
769
+ columnId = input(null, { ...(ngDevMode ? { debugName: "columnId" } : {}), alias: 'tngTableColumnId',
770
+ transform: normalizeOptionalString });
771
+ stickyColumn = input(null, { ...(ngDevMode ? { debugName: "stickyColumn" } : {}), alias: 'tngTableStickyColumn',
772
+ transform: normalizeTableStickySide });
773
+ stickyOffset = input(null, { ...(ngDevMode ? { debugName: "stickyOffset" } : {}), alias: 'tngTableStickyOffset',
774
+ transform: normalizeCssLength });
775
+ truncate = input(false, { ...(ngDevMode ? { debugName: "truncate" } : {}), alias: 'tngTableTruncate',
776
+ transform: booleanAttribute });
777
+ dataSlot = 'table-header-cell';
778
+ get dataColumnIdAttr() {
779
+ return this.columnId();
780
+ }
781
+ get dataStickyAttr() {
782
+ return this.isSectionSticky() || this.getStickySide() !== null ? '' : null;
783
+ }
784
+ get dataStickyHeaderAttr() {
785
+ return this.header?.isSticky() === true ? '' : null;
786
+ }
787
+ get dataStickySideAttr() {
788
+ return this.getStickySide();
789
+ }
790
+ get dataTruncateAttr() {
791
+ return this.truncate() ? '' : null;
792
+ }
793
+ get tabIndexAttr() {
794
+ return this.table.getCellTabIndex(this);
795
+ }
796
+ get leftAttr() {
797
+ return this.table.getCellStickyInset(this, 'left');
798
+ }
799
+ get overflowAttr() {
800
+ return this.truncate() ? 'hidden' : null;
801
+ }
802
+ get positionAttr() {
803
+ return this.table.getCellStickyPosition(this);
804
+ }
805
+ get rightAttr() {
806
+ return this.table.getCellStickyInset(this, 'right');
807
+ }
808
+ get textOverflowAttr() {
809
+ return this.truncate() ? 'ellipsis' : null;
810
+ }
811
+ get topAttr() {
812
+ return this.header?.isSticky() === true ? this.header.getStickyInset() : null;
813
+ }
814
+ get whiteSpaceAttr() {
815
+ return this.truncate() ? 'nowrap' : null;
816
+ }
817
+ get zIndexAttr() {
818
+ return this.table.getCellStickyZIndex(this);
819
+ }
820
+ get dataFocusedAttr() {
821
+ return this.table.isCellFocused(this) ? '' : null;
822
+ }
823
+ get dataFocusVisibleAttr() {
824
+ return this.table.isCellFocusVisible(this) ? '' : null;
825
+ }
826
+ ngOnDestroy() {
827
+ this.table.onCellDestroy(this);
828
+ }
829
+ ngOnInit() {
830
+ this.table.registerCell(this);
831
+ }
832
+ cellKey() {
833
+ const position = this.getCellPosition();
834
+ return position === null ? null : createTngTableCellKey(position);
835
+ }
836
+ focusHost() {
837
+ this.hostRef.nativeElement.focus();
838
+ }
839
+ getCellPosition() {
840
+ return resolveTngTableCellPosition(this.hostRef.nativeElement);
841
+ }
842
+ getHostElement() {
843
+ return this.hostRef.nativeElement;
844
+ }
845
+ getStickyOffset() {
846
+ return this.stickyOffset();
847
+ }
848
+ getStickySide() {
849
+ return this.stickyColumn();
850
+ }
851
+ isDisabled() {
852
+ return false;
853
+ }
854
+ isFocusVisible() {
855
+ return isFocusVisibleElement(this.hostRef.nativeElement);
856
+ }
857
+ isSectionSticky() {
858
+ return this.header?.isSticky() === true;
859
+ }
860
+ onFocus() {
861
+ this.table.onCellFocused(this);
862
+ }
863
+ onPointerDown() {
864
+ this.table.onCellPointerDown(this);
865
+ }
866
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableHeaderCell, deps: [], target: i0.ɵɵFactoryTarget.Directive });
867
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableHeaderCell, isStandalone: true, selector: "th[tngTableHeaderCell]", inputs: { columnId: { classPropertyName: "columnId", publicName: "tngTableColumnId", isSignal: true, isRequired: false, transformFunction: null }, stickyColumn: { classPropertyName: "stickyColumn", publicName: "tngTableStickyColumn", isSignal: true, isRequired: false, transformFunction: null }, stickyOffset: { classPropertyName: "stickyOffset", publicName: "tngTableStickyOffset", isSignal: true, isRequired: false, transformFunction: null }, truncate: { classPropertyName: "truncate", publicName: "tngTableTruncate", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "focus": "onFocus()", "pointerdown": "onPointerDown()" }, properties: { "attr.data-slot": "this.dataSlot", "attr.data-column-id": "this.dataColumnIdAttr", "attr.data-sticky": "this.dataStickyAttr", "attr.data-sticky-header": "this.dataStickyHeaderAttr", "attr.data-sticky-side": "this.dataStickySideAttr", "attr.data-truncate": "this.dataTruncateAttr", "attr.tabindex": "this.tabIndexAttr", "style.left": "this.leftAttr", "style.overflow": "this.overflowAttr", "style.position": "this.positionAttr", "style.right": "this.rightAttr", "style.text-overflow": "this.textOverflowAttr", "style.top": "this.topAttr", "style.white-space": "this.whiteSpaceAttr", "style.z-index": "this.zIndexAttr", "attr.data-focused": "this.dataFocusedAttr", "attr.data-focus-visible": "this.dataFocusVisibleAttr" } }, exportAs: ["tngTableHeaderCell"], ngImport: i0 });
868
+ }
869
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableHeaderCell, decorators: [{
870
+ type: Directive,
871
+ args: [{
872
+ selector: 'th[tngTableHeaderCell]',
873
+ exportAs: 'tngTableHeaderCell',
874
+ }]
875
+ }], propDecorators: { columnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnId", required: false }] }], stickyColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableStickyColumn", required: false }] }], stickyOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableStickyOffset", required: false }] }], truncate: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableTruncate", required: false }] }], dataSlot: [{
876
+ type: HostBinding,
877
+ args: ['attr.data-slot']
878
+ }], dataColumnIdAttr: [{
879
+ type: HostBinding,
880
+ args: ['attr.data-column-id']
881
+ }], dataStickyAttr: [{
882
+ type: HostBinding,
883
+ args: ['attr.data-sticky']
884
+ }], dataStickyHeaderAttr: [{
885
+ type: HostBinding,
886
+ args: ['attr.data-sticky-header']
887
+ }], dataStickySideAttr: [{
888
+ type: HostBinding,
889
+ args: ['attr.data-sticky-side']
890
+ }], dataTruncateAttr: [{
891
+ type: HostBinding,
892
+ args: ['attr.data-truncate']
893
+ }], tabIndexAttr: [{
894
+ type: HostBinding,
895
+ args: ['attr.tabindex']
896
+ }], leftAttr: [{
897
+ type: HostBinding,
898
+ args: ['style.left']
899
+ }], overflowAttr: [{
900
+ type: HostBinding,
901
+ args: ['style.overflow']
902
+ }], positionAttr: [{
903
+ type: HostBinding,
904
+ args: ['style.position']
905
+ }], rightAttr: [{
906
+ type: HostBinding,
907
+ args: ['style.right']
908
+ }], textOverflowAttr: [{
909
+ type: HostBinding,
910
+ args: ['style.text-overflow']
911
+ }], topAttr: [{
912
+ type: HostBinding,
913
+ args: ['style.top']
914
+ }], whiteSpaceAttr: [{
915
+ type: HostBinding,
916
+ args: ['style.white-space']
917
+ }], zIndexAttr: [{
918
+ type: HostBinding,
919
+ args: ['style.z-index']
920
+ }], dataFocusedAttr: [{
921
+ type: HostBinding,
922
+ args: ['attr.data-focused']
923
+ }], dataFocusVisibleAttr: [{
924
+ type: HostBinding,
925
+ args: ['attr.data-focus-visible']
926
+ }], onFocus: [{
927
+ type: HostListener,
928
+ args: ['focus']
929
+ }], onPointerDown: [{
930
+ type: HostListener,
931
+ args: ['pointerdown']
932
+ }] } });
933
+ export class TngTableEmpty {
934
+ dataSlot = 'table-empty';
935
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableEmpty, deps: [], target: i0.ɵɵFactoryTarget.Directive });
936
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTableEmpty, isStandalone: true, selector: "[tngTableEmpty]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableEmpty"], ngImport: i0 });
937
+ }
938
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableEmpty, decorators: [{
939
+ type: Directive,
940
+ args: [{
941
+ selector: '[tngTableEmpty]',
942
+ exportAs: 'tngTableEmpty',
943
+ }]
944
+ }], propDecorators: { dataSlot: [{
945
+ type: HostBinding,
946
+ args: ['attr.data-slot']
947
+ }] } });
948
+ export class TngTableLoading {
949
+ dataSlot = 'table-loading';
950
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableLoading, deps: [], target: i0.ɵɵFactoryTarget.Directive });
951
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTableLoading, isStandalone: true, selector: "[tngTableLoading]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableLoading"], ngImport: i0 });
952
+ }
953
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableLoading, decorators: [{
954
+ type: Directive,
955
+ args: [{
956
+ selector: '[tngTableLoading]',
957
+ exportAs: 'tngTableLoading',
958
+ }]
959
+ }], propDecorators: { dataSlot: [{
960
+ type: HostBinding,
961
+ args: ['attr.data-slot']
962
+ }] } });
963
+ export class TngTableError {
964
+ dataSlot = 'table-error';
965
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableError, deps: [], target: i0.ɵɵFactoryTarget.Directive });
966
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTableError, isStandalone: true, selector: "[tngTableError]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableError"], ngImport: i0 });
967
+ }
968
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableError, decorators: [{
969
+ type: Directive,
970
+ args: [{
971
+ selector: '[tngTableError]',
972
+ exportAs: 'tngTableError',
973
+ }]
974
+ }], propDecorators: { dataSlot: [{
975
+ type: HostBinding,
976
+ args: ['attr.data-slot']
977
+ }] } });
978
+ export class TngTableToolbar {
979
+ dataSlot = 'table-toolbar';
980
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableToolbar, deps: [], target: i0.ɵɵFactoryTarget.Directive });
981
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTableToolbar, isStandalone: true, selector: "[tngTableToolbar]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableToolbar"], ngImport: i0 });
982
+ }
983
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableToolbar, decorators: [{
984
+ type: Directive,
985
+ args: [{
986
+ selector: '[tngTableToolbar]',
987
+ exportAs: 'tngTableToolbar',
988
+ }]
989
+ }], propDecorators: { dataSlot: [{
990
+ type: HostBinding,
991
+ args: ['attr.data-slot']
992
+ }] } });
993
+ export class TngTablePagination {
994
+ dataSlot = 'table-pagination';
995
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTablePagination, deps: [], target: i0.ɵɵFactoryTarget.Directive });
996
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: TngTablePagination, isStandalone: true, selector: "[tngTablePagination]", host: { properties: { "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTablePagination"], ngImport: i0 });
997
+ }
998
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTablePagination, decorators: [{
999
+ type: Directive,
1000
+ args: [{
1001
+ selector: '[tngTablePagination]',
1002
+ exportAs: 'tngTablePagination',
1003
+ }]
1004
+ }], propDecorators: { dataSlot: [{
1005
+ type: HostBinding,
1006
+ args: ['attr.data-slot']
1007
+ }] } });
1008
+ export class TngTableRowExpander {
1009
+ expansion = inject(forwardRef(() => TngTableExpansion), {
1010
+ optional: true,
1011
+ });
1012
+ hostRef = inject(ElementRef);
1013
+ rowId = input.required({ ...(ngDevMode ? { debugName: "rowId" } : {}), alias: 'tngTableRowExpander' });
1014
+ get ariaExpandedAttr() {
1015
+ if (this.expansion === null) {
1016
+ return null;
1017
+ }
1018
+ return this.expansion.isExpanded(this.rowId()) ? 'true' : 'false';
1019
+ }
1020
+ get dataExpandedAttr() {
1021
+ return this.expansion?.isExpanded(this.rowId()) ? '' : null;
1022
+ }
1023
+ dataSlot = 'table-row-expander';
1024
+ onClick() {
1025
+ this.toggle('pointer');
1026
+ }
1027
+ onKeydown(event) {
1028
+ if (this.isNativeButton()) {
1029
+ return;
1030
+ }
1031
+ if (event.key !== 'Enter' && event.key !== ' ') {
1032
+ return;
1033
+ }
1034
+ event.preventDefault();
1035
+ this.toggle('keyboard');
1036
+ }
1037
+ isNativeButton() {
1038
+ return this.hostRef.nativeElement.tagName === 'BUTTON';
1039
+ }
1040
+ toggle(trigger) {
1041
+ this.expansion?.toggle(this.rowId(), trigger);
1042
+ }
1043
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableRowExpander, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1044
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableRowExpander, isStandalone: true, selector: "[tngTableRowExpander]", inputs: { rowId: { classPropertyName: "rowId", publicName: "tngTableRowExpander", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown": "onKeydown($event)" }, properties: { "attr.aria-expanded": "this.ariaExpandedAttr", "attr.data-expanded": "this.dataExpandedAttr", "attr.data-slot": "this.dataSlot" } }, exportAs: ["tngTableRowExpander"], ngImport: i0 });
1045
+ }
1046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableRowExpander, decorators: [{
1047
+ type: Directive,
1048
+ args: [{
1049
+ selector: '[tngTableRowExpander]',
1050
+ exportAs: 'tngTableRowExpander',
1051
+ }]
1052
+ }], propDecorators: { rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableRowExpander", required: true }] }], ariaExpandedAttr: [{
1053
+ type: HostBinding,
1054
+ args: ['attr.aria-expanded']
1055
+ }], dataExpandedAttr: [{
1056
+ type: HostBinding,
1057
+ args: ['attr.data-expanded']
1058
+ }], dataSlot: [{
1059
+ type: HostBinding,
1060
+ args: ['attr.data-slot']
1061
+ }], onClick: [{
1062
+ type: HostListener,
1063
+ args: ['click']
1064
+ }], onKeydown: [{
1065
+ type: HostListener,
1066
+ args: ['keydown', ['$event']]
1067
+ }] } });
1068
+ export class TngTable {
1069
+ hostRef = inject(ElementRef);
1070
+ headerSlots = contentChildren(TngTableHeader, ...(ngDevMode ? [{ debugName: "headerSlots" }] : []));
1071
+ footerSlots = contentChildren(TngTableFooter, ...(ngDevMode ? [{ debugName: "footerSlots" }] : []));
1072
+ cells = new Set();
1073
+ activeCell = null;
1074
+ domFocusedCell = null;
1075
+ focusVisibleCell = null;
1076
+ pendingFocusTrigger = null;
1077
+ restoreFocusElement = null;
1078
+ shouldRestoreFocusOnDestroy = false;
1079
+ items = input(undefined, ...(ngDevMode ? [{ debugName: "items" }] : []));
1080
+ error = input(false, { ...(ngDevMode ? { debugName: "error" } : {}), transform: booleanAttribute });
1081
+ filterable = input(false, { ...(ngDevMode ? { debugName: "filterable" } : {}), transform: booleanAttribute });
1082
+ layout = input('auto', { ...(ngDevMode ? { debugName: "layout" } : {}), alias: 'tngTableLayout',
1083
+ transform: normalizeTableLayoutMode });
1084
+ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : {}), transform: booleanAttribute });
1085
+ pageable = input(false, { ...(ngDevMode ? { debugName: "pageable" } : {}), transform: booleanAttribute });
1086
+ rowId = input(null, ...(ngDevMode ? [{ debugName: "rowId" }] : []));
1087
+ dir = input(null, { ...(ngDevMode ? { debugName: "dir" } : {}), transform: normalizeTableDirection });
1088
+ ariaLabelValue = null;
1089
+ ariaLabelledbyValue = null;
1090
+ set ariaLabel(value) {
1091
+ this.ariaLabelValue = normalizeOptionalString(value);
1092
+ }
1093
+ set ariaLabelledby(value) {
1094
+ this.ariaLabelledbyValue = normalizeOptionalString(value);
1095
+ }
1096
+ dataSlot = 'table';
1097
+ get ariaLabelAttr() {
1098
+ return this.ariaLabelValue;
1099
+ }
1100
+ get ariaLabelledbyAttr() {
1101
+ return this.ariaLabelledbyValue;
1102
+ }
1103
+ get dataEmptyAttr() {
1104
+ return resolveTngTableEmptyState(this.items(), this.loading()) ? '' : null;
1105
+ }
1106
+ get dataErrorAttr() {
1107
+ return this.error() ? '' : null;
1108
+ }
1109
+ get dataFilterableAttr() {
1110
+ return this.filterable() ? '' : null;
1111
+ }
1112
+ get dataHasFooterAttr() {
1113
+ return this.footerSlots().length > 0 ? '' : null;
1114
+ }
1115
+ get dataHasHeaderAttr() {
1116
+ return this.headerSlots().length > 0 ? '' : null;
1117
+ }
1118
+ get dataLayoutAttr() {
1119
+ return this.layout();
1120
+ }
1121
+ get dataLoadingAttr() {
1122
+ return this.loading() ? '' : null;
1123
+ }
1124
+ get dataPageableAttr() {
1125
+ return this.pageable() ? '' : null;
1126
+ }
1127
+ get dirAttr() {
1128
+ return this.dir();
1129
+ }
1130
+ get tableLayoutAttr() {
1131
+ return this.layout();
1132
+ }
1133
+ ngOnDestroy() {
1134
+ const activeElement = this.hostRef.nativeElement.ownerDocument.activeElement;
1135
+ const restoreFocusElement = this.getRestoreFocusElement();
1136
+ const shouldRestoreFocus = restoreFocusElement !== null
1137
+ && (this.shouldRestoreFocusOnDestroy
1138
+ || this.domFocusedCell !== null
1139
+ || isInsideContainer(this.hostRef.nativeElement, activeElement));
1140
+ if (shouldRestoreFocus) {
1141
+ restoreFocusElement.focus();
1142
+ queueMicrotask(() => {
1143
+ if (restoreFocusElement.isConnected) {
1144
+ restoreFocusElement.focus();
1145
+ }
1146
+ });
1147
+ }
1148
+ this.cells.clear();
1149
+ this.activeCell = null;
1150
+ this.domFocusedCell = null;
1151
+ this.focusVisibleCell = null;
1152
+ this.pendingFocusTrigger = null;
1153
+ this.restoreFocusElement = null;
1154
+ this.shouldRestoreFocusOnDestroy = false;
1155
+ }
1156
+ getCellTabIndex(cell) {
1157
+ if (this.isCellDisabled(cell)) {
1158
+ return '-1';
1159
+ }
1160
+ return this.getActiveCell() === cell ? '0' : '-1';
1161
+ }
1162
+ isCellFocusVisible(cell) {
1163
+ return this.focusVisibleCell === cell;
1164
+ }
1165
+ isCellFocused(cell) {
1166
+ return this.domFocusedCell === cell;
1167
+ }
1168
+ getCellStickyInset(cell, physicalSide) {
1169
+ const stickySide = cell.getStickySide();
1170
+ if (stickySide === null || resolveStickyPhysicalSide(stickySide, this.dir()) !== physicalSide) {
1171
+ return null;
1172
+ }
1173
+ return cell.getStickyOffset() ?? '0px';
1174
+ }
1175
+ getCellStickyPosition(cell) {
1176
+ return cell.isSectionSticky() || cell.getStickySide() !== null ? 'sticky' : null;
1177
+ }
1178
+ getCellStickyZIndex(cell) {
1179
+ if (cell.isSectionSticky() && cell.getStickySide() !== null) {
1180
+ return '4';
1181
+ }
1182
+ if (cell.isSectionSticky()) {
1183
+ return '3';
1184
+ }
1185
+ return cell.getStickySide() !== null ? '2' : null;
1186
+ }
1187
+ onCellFocused(cell) {
1188
+ if (this.isCellDisabled(cell)) {
1189
+ return;
1190
+ }
1191
+ const trigger = this.pendingFocusTrigger ?? 'programmatic';
1192
+ this.pendingFocusTrigger = null;
1193
+ this.activeCell = cell;
1194
+ this.domFocusedCell = cell;
1195
+ this.focusVisibleCell =
1196
+ trigger === 'keyboard' || cell.isFocusVisible()
1197
+ ? cell
1198
+ : null;
1199
+ }
1200
+ onCellDestroy(cell) {
1201
+ if (this.domFocusedCell === cell
1202
+ || this.hostRef.nativeElement.ownerDocument.activeElement === cell.getHostElement()) {
1203
+ this.shouldRestoreFocusOnDestroy = true;
1204
+ }
1205
+ this.unregisterCell(cell);
1206
+ }
1207
+ onCellPointerDown(cell) {
1208
+ if (this.isCellDisabled(cell)) {
1209
+ return;
1210
+ }
1211
+ this.pendingFocusTrigger = 'pointer';
1212
+ this.focusVisibleCell = null;
1213
+ }
1214
+ registerCell(cell) {
1215
+ this.cells.add(cell);
1216
+ this.ensureFallbackActiveCell();
1217
+ }
1218
+ unregisterCell(cell) {
1219
+ this.cells.delete(cell);
1220
+ if (this.activeCell === cell) {
1221
+ this.activeCell = null;
1222
+ }
1223
+ if (this.domFocusedCell === cell) {
1224
+ this.domFocusedCell = null;
1225
+ }
1226
+ if (this.focusVisibleCell === cell) {
1227
+ this.focusVisibleCell = null;
1228
+ }
1229
+ this.ensureFallbackActiveCell();
1230
+ }
1231
+ onFocusIn(event) {
1232
+ if (isInsideContainer(this.hostRef.nativeElement, event.relatedTarget)) {
1233
+ return;
1234
+ }
1235
+ if (event.relatedTarget instanceof HTMLElement) {
1236
+ this.restoreFocusElement = event.relatedTarget;
1237
+ }
1238
+ }
1239
+ onFocusOut(event) {
1240
+ if (isInsideContainer(this.hostRef.nativeElement, event.relatedTarget)) {
1241
+ return;
1242
+ }
1243
+ this.domFocusedCell = null;
1244
+ this.focusVisibleCell = null;
1245
+ this.pendingFocusTrigger = null;
1246
+ }
1247
+ onKeyDown(event) {
1248
+ const activeCell = this.getKeydownActiveCell(event);
1249
+ if (activeCell === null) {
1250
+ return;
1251
+ }
1252
+ if (this.handleEscapeKey(event)) {
1253
+ return;
1254
+ }
1255
+ if (this.handlePageNavigation(event, activeCell)) {
1256
+ return;
1257
+ }
1258
+ const action = resolveGridNavigationKeyAction(event, {
1259
+ direction: this.dir() ?? 'ltr',
1260
+ });
1261
+ if (action === null || !isMovementActionType(action.type)) {
1262
+ return;
1263
+ }
1264
+ if (action.preventDefault) {
1265
+ event.preventDefault();
1266
+ }
1267
+ this.moveFocus(activeCell, action.type);
1268
+ }
1269
+ ensureFallbackActiveCell() {
1270
+ if (this.activeCell !== null && this.cells.has(this.activeCell) && !this.isCellDisabled(this.activeCell)) {
1271
+ return;
1272
+ }
1273
+ this.activeCell = this.getFirstEnabledCell();
1274
+ }
1275
+ findCellByPosition(position) {
1276
+ for (const cell of this.cells) {
1277
+ const candidate = cell.getCellPosition();
1278
+ if (candidate?.row === position.row && candidate.col === position.col) {
1279
+ return cell;
1280
+ }
1281
+ }
1282
+ return null;
1283
+ }
1284
+ focusCell(cell, trigger) {
1285
+ this.activeCell = cell;
1286
+ this.pendingFocusTrigger = trigger;
1287
+ if (trigger === 'keyboard') {
1288
+ this.focusVisibleCell = cell;
1289
+ }
1290
+ cell.focusHost();
1291
+ }
1292
+ getActiveCell() {
1293
+ this.ensureFallbackActiveCell();
1294
+ return this.activeCell;
1295
+ }
1296
+ getBoundaryCell(cells, direction) {
1297
+ return direction === 'forward'
1298
+ ? cells[cells.length - 1] ?? null
1299
+ : cells[0] ?? null;
1300
+ }
1301
+ getComputedBounds() {
1302
+ let maxCol = 0;
1303
+ let maxRow = 0;
1304
+ for (const cell of this.cells) {
1305
+ const position = cell.getCellPosition();
1306
+ if (position === null) {
1307
+ continue;
1308
+ }
1309
+ maxCol = Math.max(maxCol, position.col);
1310
+ maxRow = Math.max(maxRow, position.row);
1311
+ }
1312
+ return Object.freeze({
1313
+ colCount: maxCol + 1,
1314
+ rowCount: maxRow + 1,
1315
+ });
1316
+ }
1317
+ getEnabledCells() {
1318
+ return [...this.cells]
1319
+ .filter((cell) => !this.isCellDisabled(cell) && cell.getCellPosition() !== null)
1320
+ .sort((a, b) => {
1321
+ const aPosition = a.getCellPosition();
1322
+ const bPosition = b.getCellPosition();
1323
+ if (aPosition === null && bPosition === null) {
1324
+ return 0;
1325
+ }
1326
+ if (aPosition === null) {
1327
+ return 1;
1328
+ }
1329
+ if (bPosition === null) {
1330
+ return -1;
1331
+ }
1332
+ return compareTngTableCellPositions(aPosition, bPosition);
1333
+ });
1334
+ }
1335
+ getFirstEnabledCell() {
1336
+ return this.getEnabledCells()[0] ?? null;
1337
+ }
1338
+ getNavigableCells() {
1339
+ const navigableCells = [];
1340
+ for (const cell of this.cells) {
1341
+ const position = cell.getCellPosition();
1342
+ if (position === null) {
1343
+ continue;
1344
+ }
1345
+ navigableCells.push({
1346
+ col: position.col,
1347
+ disabled: this.isCellDisabled(cell),
1348
+ row: position.row,
1349
+ });
1350
+ }
1351
+ return navigableCells;
1352
+ }
1353
+ getKeydownActiveCell(event) {
1354
+ const activeCell = this.getActiveCell();
1355
+ if (activeCell === null || this.isCellDisabled(activeCell)) {
1356
+ return null;
1357
+ }
1358
+ return event.target === activeCell.getHostElement() ? activeCell : null;
1359
+ }
1360
+ getRestoreFocusElement() {
1361
+ if (!this.restoreFocusElement?.isConnected) {
1362
+ return null;
1363
+ }
1364
+ return this.hostRef.nativeElement.contains(this.restoreFocusElement)
1365
+ ? null
1366
+ : this.restoreFocusElement;
1367
+ }
1368
+ handleEscapeKey(event) {
1369
+ if (event.key !== 'Escape' || hasTableKeyboardModifiers(event)) {
1370
+ return false;
1371
+ }
1372
+ event.preventDefault();
1373
+ const restoreFocusElement = this.getRestoreFocusElement();
1374
+ if (restoreFocusElement !== null) {
1375
+ this.pendingFocusTrigger = 'programmatic';
1376
+ restoreFocusElement.focus();
1377
+ return true;
1378
+ }
1379
+ const activeElement = this.hostRef.nativeElement.ownerDocument.activeElement;
1380
+ if (activeElement instanceof HTMLElement) {
1381
+ activeElement.blur();
1382
+ }
1383
+ return true;
1384
+ }
1385
+ handlePageNavigation(event, activeCell) {
1386
+ const direction = resolveTngTablePageDirection(event.key);
1387
+ if (direction === null || hasTableKeyboardModifiers(event)) {
1388
+ return false;
1389
+ }
1390
+ const currentPosition = activeCell.getCellPosition();
1391
+ const enabledCells = this.getEnabledCells();
1392
+ if (currentPosition === null || enabledCells.length === 0) {
1393
+ return true;
1394
+ }
1395
+ event.preventDefault();
1396
+ const sameColumnCells = enabledCells.filter((cell) => {
1397
+ const position = cell.getCellPosition();
1398
+ return position !== null && position.col === currentPosition.col;
1399
+ });
1400
+ const targetCell = this.getBoundaryCell(sameColumnCells, direction)
1401
+ ?? this.getBoundaryCell(enabledCells, direction);
1402
+ if (targetCell !== null) {
1403
+ this.focusCell(targetCell, 'keyboard');
1404
+ }
1405
+ return true;
1406
+ }
1407
+ isCellDisabled(cell) {
1408
+ return cell.isDisabled();
1409
+ }
1410
+ moveFocus(activeCell, actionType) {
1411
+ const currentPosition = activeCell.getCellPosition();
1412
+ if (currentPosition === null) {
1413
+ return;
1414
+ }
1415
+ const nextPosition = resolveNavigableGridCell(currentPosition, actionType, {
1416
+ bounds: this.getComputedBounds(),
1417
+ cells: this.getNavigableCells(),
1418
+ });
1419
+ if (nextPosition === null) {
1420
+ return;
1421
+ }
1422
+ const nextCell = this.findCellByPosition(nextPosition);
1423
+ if (nextCell === null || this.isCellDisabled(nextCell)) {
1424
+ return;
1425
+ }
1426
+ this.focusCell(nextCell, 'keyboard');
1427
+ }
1428
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1429
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.1.1", type: TngTable, isStandalone: true, selector: "table[tngTable]", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, filterable: { classPropertyName: "filterable", publicName: "filterable", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "tngTableLayout", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, pageable: { classPropertyName: "pageable", publicName: "pageable", isSignal: true, isRequired: false, transformFunction: null }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null }, dir: { classPropertyName: "dir", publicName: "dir", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: false, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "ariaLabelledby", isSignal: false, isRequired: false, transformFunction: null } }, host: { listeners: { "focusin": "onFocusIn($event)", "focusout": "onFocusOut($event)", "keydown": "onKeyDown($event)" }, properties: { "attr.data-slot": "this.dataSlot", "attr.aria-label": "this.ariaLabelAttr", "attr.aria-labelledby": "this.ariaLabelledbyAttr", "attr.data-empty": "this.dataEmptyAttr", "attr.data-error": "this.dataErrorAttr", "attr.data-filterable": "this.dataFilterableAttr", "attr.data-has-footer": "this.dataHasFooterAttr", "attr.data-has-header": "this.dataHasHeaderAttr", "attr.data-layout": "this.dataLayoutAttr", "attr.data-loading": "this.dataLoadingAttr", "attr.data-pageable": "this.dataPageableAttr", "attr.dir": "this.dirAttr", "style.table-layout": "this.tableLayoutAttr" } }, queries: [{ propertyName: "headerSlots", predicate: TngTableHeader, isSignal: true }, { propertyName: "footerSlots", predicate: TngTableFooter, isSignal: true }], exportAs: ["tngTable"], ngImport: i0 });
1430
+ }
1431
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTable, decorators: [{
1432
+ type: Directive,
1433
+ args: [{
1434
+ selector: 'table[tngTable]',
1435
+ exportAs: 'tngTable',
1436
+ }]
1437
+ }], propDecorators: { headerSlots: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TngTableHeader), { isSignal: true }] }], footerSlots: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => TngTableFooter), { isSignal: true }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], filterable: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterable", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableLayout", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], pageable: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageable", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], dir: [{ type: i0.Input, args: [{ isSignal: true, alias: "dir", required: false }] }], ariaLabel: [{
1438
+ type: Input
1439
+ }], ariaLabelledby: [{
1440
+ type: Input
1441
+ }], dataSlot: [{
1442
+ type: HostBinding,
1443
+ args: ['attr.data-slot']
1444
+ }], ariaLabelAttr: [{
1445
+ type: HostBinding,
1446
+ args: ['attr.aria-label']
1447
+ }], ariaLabelledbyAttr: [{
1448
+ type: HostBinding,
1449
+ args: ['attr.aria-labelledby']
1450
+ }], dataEmptyAttr: [{
1451
+ type: HostBinding,
1452
+ args: ['attr.data-empty']
1453
+ }], dataErrorAttr: [{
1454
+ type: HostBinding,
1455
+ args: ['attr.data-error']
1456
+ }], dataFilterableAttr: [{
1457
+ type: HostBinding,
1458
+ args: ['attr.data-filterable']
1459
+ }], dataHasFooterAttr: [{
1460
+ type: HostBinding,
1461
+ args: ['attr.data-has-footer']
1462
+ }], dataHasHeaderAttr: [{
1463
+ type: HostBinding,
1464
+ args: ['attr.data-has-header']
1465
+ }], dataLayoutAttr: [{
1466
+ type: HostBinding,
1467
+ args: ['attr.data-layout']
1468
+ }], dataLoadingAttr: [{
1469
+ type: HostBinding,
1470
+ args: ['attr.data-loading']
1471
+ }], dataPageableAttr: [{
1472
+ type: HostBinding,
1473
+ args: ['attr.data-pageable']
1474
+ }], dirAttr: [{
1475
+ type: HostBinding,
1476
+ args: ['attr.dir']
1477
+ }], tableLayoutAttr: [{
1478
+ type: HostBinding,
1479
+ args: ['style.table-layout']
1480
+ }], onFocusIn: [{
1481
+ type: HostListener,
1482
+ args: ['focusin', ['$event']]
1483
+ }], onFocusOut: [{
1484
+ type: HostListener,
1485
+ args: ['focusout', ['$event']]
1486
+ }], onKeyDown: [{
1487
+ type: HostListener,
1488
+ args: ['keydown', ['$event']]
1489
+ }] } });
1490
+ //# sourceMappingURL=tng-table.js.map