@tailng-ui/primitives 0.40.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,361 @@
1
+ import { Directive, ElementRef, HostBinding, HostListener, booleanAttribute, forwardRef, inject, input, output, } from '@angular/core';
2
+ import { TngTable, TngTableCell, TngTableHeaderCell } from './tng-table';
3
+ import * as i0 from "@angular/core";
4
+ function normalizeCssLength(value) {
5
+ if (typeof value === 'number' && Number.isFinite(value)) {
6
+ return `${value}px`;
7
+ }
8
+ if (typeof value !== 'string') {
9
+ return null;
10
+ }
11
+ const trimmed = value.trim();
12
+ return trimmed.length > 0 ? trimmed : null;
13
+ }
14
+ function normalizeOptionalString(value) {
15
+ if (typeof value !== 'string') {
16
+ return null;
17
+ }
18
+ const trimmed = value.trim();
19
+ return trimmed.length > 0 ? trimmed : null;
20
+ }
21
+ function normalizeWidthMap(value) {
22
+ if (typeof value !== 'object' || value === null) {
23
+ return {};
24
+ }
25
+ const nextWidths = {};
26
+ for (const [columnId, columnWidth] of Object.entries(value)) {
27
+ const normalizedWidth = normalizeCssLength(columnWidth);
28
+ if (normalizedWidth !== null) {
29
+ nextWidths[columnId] = normalizedWidth;
30
+ }
31
+ }
32
+ return nextWidths;
33
+ }
34
+ function parsePixelLength(value) {
35
+ if (value === null) {
36
+ return null;
37
+ }
38
+ const trimmed = value.trim();
39
+ if (/^-?\d+(\.\d+)?px$/u.test(trimmed)) {
40
+ return Number.parseFloat(trimmed.slice(0, -2));
41
+ }
42
+ if (/^-?\d+(\.\d+)?$/u.test(trimmed)) {
43
+ return Number.parseFloat(trimmed);
44
+ }
45
+ return null;
46
+ }
47
+ function measureWidth(element) {
48
+ const rectWidth = element.getBoundingClientRect().width;
49
+ if (Number.isFinite(rectWidth) && rectWidth > 0) {
50
+ return rectWidth;
51
+ }
52
+ return element.offsetWidth;
53
+ }
54
+ export class TngTableColumnSizing {
55
+ columns = new Set();
56
+ table = inject(TngTable);
57
+ uncontrolledWidths = {};
58
+ resizingColumnId = null;
59
+ widths = input(undefined, { ...(ngDevMode ? { debugName: "widths" } : {}), alias: 'tngTableColumnWidths' });
60
+ columnWidthsChange = output();
61
+ dataColumnSizing = '';
62
+ getResolvedMaxWidth(column) {
63
+ const columnId = column.getColumnId();
64
+ return columnId === null ? column.getMaxWidth() : this.resolveColumnMaxWidth(columnId);
65
+ }
66
+ getResolvedMinWidth(column) {
67
+ const columnId = column.getColumnId();
68
+ return columnId === null ? column.getMinWidth() : this.resolveColumnMinWidth(columnId);
69
+ }
70
+ getResolvedWidth(column) {
71
+ const columnId = column.getColumnId();
72
+ if (columnId === null) {
73
+ return column.getDefaultWidth();
74
+ }
75
+ return this.clampWidthValue(this.getCurrentWidths()[columnId] ?? this.resolveColumnDefaultWidth(columnId) ?? column.getDefaultWidth(), columnId);
76
+ }
77
+ isResizing(columnId) {
78
+ return columnId !== null && this.resizingColumnId === columnId;
79
+ }
80
+ registerColumn(column) {
81
+ this.columns.add(column);
82
+ }
83
+ resize(columnId, startWidth, delta) {
84
+ const signedDelta = this.table.dir() === 'rtl' ? -delta : delta;
85
+ const nextWidth = this.clampPixelWidth(columnId, startWidth + signedDelta);
86
+ this.resizingColumnId = columnId;
87
+ this.commit({
88
+ ...this.getCurrentWidths(),
89
+ [columnId]: `${nextWidth}px`,
90
+ });
91
+ }
92
+ resolveColumnPixelWidth(columnId) {
93
+ const resolvedWidth = this.clampWidthValue(this.getCurrentWidths()[columnId] ?? this.resolveColumnDefaultWidth(columnId), columnId);
94
+ const parsedWidth = parsePixelLength(resolvedWidth);
95
+ if (parsedWidth !== null) {
96
+ return parsedWidth;
97
+ }
98
+ const measuredWidth = this.resolveMeasuredWidth(columnId);
99
+ return measuredWidth ?? 0;
100
+ }
101
+ stopResize() {
102
+ this.resizingColumnId = null;
103
+ }
104
+ unregisterColumn(column) {
105
+ this.columns.delete(column);
106
+ }
107
+ clampPixelWidth(columnId, width) {
108
+ const minWidth = parsePixelLength(this.resolveColumnMinWidth(columnId));
109
+ const maxWidth = parsePixelLength(this.resolveColumnMaxWidth(columnId));
110
+ let nextWidth = Math.max(0, width);
111
+ if (minWidth !== null) {
112
+ nextWidth = Math.max(nextWidth, minWidth);
113
+ }
114
+ if (maxWidth !== null) {
115
+ nextWidth = Math.min(nextWidth, maxWidth);
116
+ }
117
+ return nextWidth;
118
+ }
119
+ clampWidthValue(value, columnId) {
120
+ const parsedWidth = parsePixelLength(value);
121
+ if (parsedWidth === null) {
122
+ return value;
123
+ }
124
+ return `${this.clampPixelWidth(columnId, parsedWidth)}px`;
125
+ }
126
+ commit(nextWidths) {
127
+ if (this.widths() === undefined) {
128
+ this.uncontrolledWidths = nextWidths;
129
+ }
130
+ this.columnWidthsChange.emit(Object.freeze({ ...nextWidths }));
131
+ }
132
+ getCurrentWidths() {
133
+ return this.widths() === undefined ? this.uncontrolledWidths : normalizeWidthMap(this.widths());
134
+ }
135
+ resolveColumnDefaultWidth(columnId) {
136
+ return this.findColumnsById(columnId)
137
+ .map((column) => column.getDefaultWidth())
138
+ .find((width) => width !== null) ?? null;
139
+ }
140
+ resolveColumnMaxWidth(columnId) {
141
+ const widths = this.findColumnsById(columnId)
142
+ .map((column) => column.getMaxWidth())
143
+ .filter((width) => width !== null);
144
+ if (widths.length === 0) {
145
+ return null;
146
+ }
147
+ const pixelWidths = widths
148
+ .map((width) => parsePixelLength(width))
149
+ .filter((width) => width !== null);
150
+ if (pixelWidths.length === widths.length) {
151
+ return `${Math.min(...pixelWidths)}px`;
152
+ }
153
+ return widths[0] ?? null;
154
+ }
155
+ resolveColumnMinWidth(columnId) {
156
+ const widths = this.findColumnsById(columnId)
157
+ .map((column) => column.getMinWidth())
158
+ .filter((width) => width !== null);
159
+ if (widths.length === 0) {
160
+ return null;
161
+ }
162
+ const pixelWidths = widths
163
+ .map((width) => parsePixelLength(width))
164
+ .filter((width) => width !== null);
165
+ if (pixelWidths.length === widths.length) {
166
+ return `${Math.max(...pixelWidths)}px`;
167
+ }
168
+ return widths[0] ?? null;
169
+ }
170
+ resolveMeasuredWidth(columnId) {
171
+ const elements = this.findColumnsById(columnId).map((column) => column.getHostElement());
172
+ if (elements.length === 0) {
173
+ return null;
174
+ }
175
+ return elements.reduce((maxWidth, element) => Math.max(maxWidth, measureWidth(element)), 0);
176
+ }
177
+ findColumnsById(columnId) {
178
+ return [...this.columns].filter((column) => column.getColumnId() === columnId);
179
+ }
180
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumnSizing, deps: [], target: i0.ɵɵFactoryTarget.Directive });
181
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableColumnSizing, isStandalone: true, selector: "table[tngTable][tngTableColumnSizing]", inputs: { widths: { classPropertyName: "widths", publicName: "tngTableColumnWidths", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnWidthsChange: "columnWidthsChange" }, host: { properties: { "attr.data-column-sizing": "this.dataColumnSizing" } }, exportAs: ["tngTableColumnSizing"], ngImport: i0 });
182
+ }
183
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumnSizing, decorators: [{
184
+ type: Directive,
185
+ args: [{
186
+ selector: 'table[tngTable][tngTableColumnSizing]',
187
+ exportAs: 'tngTableColumnSizing',
188
+ }]
189
+ }], propDecorators: { widths: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnWidths", required: false }] }], columnWidthsChange: [{ type: i0.Output, args: ["columnWidthsChange"] }], dataColumnSizing: [{
190
+ type: HostBinding,
191
+ args: ['attr.data-column-sizing']
192
+ }] } });
193
+ export class TngTableColumn {
194
+ cell = inject(TngTableCell, {
195
+ optional: true,
196
+ });
197
+ headerCell = inject(TngTableHeaderCell, {
198
+ optional: true,
199
+ });
200
+ hostRef = inject(ElementRef);
201
+ sizing = inject(forwardRef(() => TngTableColumnSizing), {
202
+ optional: true,
203
+ });
204
+ columnId = input(null, { ...(ngDevMode ? { debugName: "columnId" } : {}), alias: 'tngTableColumn',
205
+ transform: normalizeOptionalString });
206
+ defaultWidth = input(null, { ...(ngDevMode ? { debugName: "defaultWidth" } : {}), alias: 'tngTableColumnWidth',
207
+ transform: normalizeCssLength });
208
+ minWidth = input(null, { ...(ngDevMode ? { debugName: "minWidth" } : {}), alias: 'tngTableColumnMinWidth',
209
+ transform: normalizeCssLength });
210
+ maxWidth = input(null, { ...(ngDevMode ? { debugName: "maxWidth" } : {}), alias: 'tngTableColumnMaxWidth',
211
+ transform: normalizeCssLength });
212
+ get dataColumnIdAttr() {
213
+ return this.getColumnId();
214
+ }
215
+ get dataColumnMaxWidthAttr() {
216
+ return this.getMaxWidth();
217
+ }
218
+ get dataColumnMinWidthAttr() {
219
+ return this.getMinWidth();
220
+ }
221
+ get dataColumnWidthAttr() {
222
+ return this.getDefaultWidth();
223
+ }
224
+ get maxWidthAttr() {
225
+ return this.sizing?.getResolvedMaxWidth(this) ?? this.getMaxWidth();
226
+ }
227
+ get minWidthAttr() {
228
+ return this.sizing?.getResolvedMinWidth(this) ?? this.getMinWidth();
229
+ }
230
+ get widthAttr() {
231
+ return this.sizing?.getResolvedWidth(this) ?? this.getDefaultWidth();
232
+ }
233
+ ngOnDestroy() {
234
+ this.sizing?.unregisterColumn(this);
235
+ }
236
+ ngOnInit() {
237
+ this.sizing?.registerColumn(this);
238
+ }
239
+ getColumnId() {
240
+ return this.columnId() ?? this.headerCell?.columnId() ?? this.cell?.columnId() ?? null;
241
+ }
242
+ getDefaultWidth() {
243
+ return this.defaultWidth();
244
+ }
245
+ getHostElement() {
246
+ return this.hostRef.nativeElement;
247
+ }
248
+ getMaxWidth() {
249
+ return this.maxWidth();
250
+ }
251
+ getMinWidth() {
252
+ return this.minWidth();
253
+ }
254
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumn, deps: [], target: i0.ɵɵFactoryTarget.Directive });
255
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableColumn, isStandalone: true, selector: "th[tngTableColumn],td[tngTableColumn]", inputs: { columnId: { classPropertyName: "columnId", publicName: "tngTableColumn", isSignal: true, isRequired: false, transformFunction: null }, defaultWidth: { classPropertyName: "defaultWidth", publicName: "tngTableColumnWidth", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "tngTableColumnMinWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "tngTableColumnMaxWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-column-id": "this.dataColumnIdAttr", "attr.data-column-max-width": "this.dataColumnMaxWidthAttr", "attr.data-column-min-width": "this.dataColumnMinWidthAttr", "attr.data-column-width": "this.dataColumnWidthAttr", "style.max-width": "this.maxWidthAttr", "style.min-width": "this.minWidthAttr", "style.width": "this.widthAttr" } }, exportAs: ["tngTableColumn"], ngImport: i0 });
256
+ }
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumn, decorators: [{
258
+ type: Directive,
259
+ args: [{
260
+ selector: 'th[tngTableColumn],td[tngTableColumn]',
261
+ exportAs: 'tngTableColumn',
262
+ }]
263
+ }], propDecorators: { columnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumn", required: false }] }], defaultWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnWidth", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnMinWidth", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnMaxWidth", required: false }] }], dataColumnIdAttr: [{
264
+ type: HostBinding,
265
+ args: ['attr.data-column-id']
266
+ }], dataColumnMaxWidthAttr: [{
267
+ type: HostBinding,
268
+ args: ['attr.data-column-max-width']
269
+ }], dataColumnMinWidthAttr: [{
270
+ type: HostBinding,
271
+ args: ['attr.data-column-min-width']
272
+ }], dataColumnWidthAttr: [{
273
+ type: HostBinding,
274
+ args: ['attr.data-column-width']
275
+ }], maxWidthAttr: [{
276
+ type: HostBinding,
277
+ args: ['style.max-width']
278
+ }], minWidthAttr: [{
279
+ type: HostBinding,
280
+ args: ['style.min-width']
281
+ }], widthAttr: [{
282
+ type: HostBinding,
283
+ args: ['style.width']
284
+ }] } });
285
+ export class TngTableColumnResizer {
286
+ sizing = inject(TngTableColumnSizing, {
287
+ optional: true,
288
+ });
289
+ activeResize = null;
290
+ columnId = input(null, { ...(ngDevMode ? { debugName: "columnId" } : {}), alias: 'tngTableColumnResizer',
291
+ transform: normalizeOptionalString });
292
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'tngTableColumnResizerDisabled',
293
+ transform: booleanAttribute });
294
+ ariaOrientation = 'vertical';
295
+ get dataResizingAttr() {
296
+ return this.sizing?.isResizing(this.columnId()) === true ? '' : null;
297
+ }
298
+ dataSlot = 'table-column-resizer';
299
+ cursor = 'col-resize';
300
+ ngOnDestroy() {
301
+ this.activeResize = null;
302
+ this.sizing?.stopResize();
303
+ }
304
+ onDocumentMouseMove(event) {
305
+ if (this.activeResize === null) {
306
+ return;
307
+ }
308
+ event.preventDefault();
309
+ this.sizing?.resize(this.activeResize.columnId, this.activeResize.startWidth, event.clientX - this.activeResize.startClientX);
310
+ }
311
+ onDocumentMouseUp() {
312
+ this.activeResize = null;
313
+ this.sizing?.stopResize();
314
+ }
315
+ onMouseDown(event) {
316
+ const columnId = this.columnId();
317
+ if (event.button !== 0
318
+ || this.disabled()
319
+ || this.sizing === null
320
+ || columnId === null) {
321
+ return;
322
+ }
323
+ event.preventDefault();
324
+ this.activeResize = Object.freeze({
325
+ columnId,
326
+ startClientX: event.clientX,
327
+ startWidth: this.sizing.resolveColumnPixelWidth(columnId),
328
+ });
329
+ }
330
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumnResizer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
331
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableColumnResizer, isStandalone: true, selector: "[tngTableColumnResizer]", inputs: { columnId: { classPropertyName: "columnId", publicName: "tngTableColumnResizer", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "tngTableColumnResizerDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:mousemove": "onDocumentMouseMove($event)", "document:mouseup": "onDocumentMouseUp()", "mousedown": "onMouseDown($event)" }, properties: { "attr.aria-orientation": "this.ariaOrientation", "attr.data-resizing": "this.dataResizingAttr", "attr.data-slot": "this.dataSlot", "style.cursor": "this.cursor" } }, exportAs: ["tngTableColumnResizer"], ngImport: i0 });
332
+ }
333
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableColumnResizer, decorators: [{
334
+ type: Directive,
335
+ args: [{
336
+ selector: '[tngTableColumnResizer]',
337
+ exportAs: 'tngTableColumnResizer',
338
+ }]
339
+ }], propDecorators: { columnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnResizer", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableColumnResizerDisabled", required: false }] }], ariaOrientation: [{
340
+ type: HostBinding,
341
+ args: ['attr.aria-orientation']
342
+ }], dataResizingAttr: [{
343
+ type: HostBinding,
344
+ args: ['attr.data-resizing']
345
+ }], dataSlot: [{
346
+ type: HostBinding,
347
+ args: ['attr.data-slot']
348
+ }], cursor: [{
349
+ type: HostBinding,
350
+ args: ['style.cursor']
351
+ }], onDocumentMouseMove: [{
352
+ type: HostListener,
353
+ args: ['document:mousemove', ['$event']]
354
+ }], onDocumentMouseUp: [{
355
+ type: HostListener,
356
+ args: ['document:mouseup']
357
+ }], onMouseDown: [{
358
+ type: HostListener,
359
+ args: ['mousedown', ['$event']]
360
+ }] } });
361
+ //# sourceMappingURL=tng-table-sizing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tng-table-sizing.js","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/layout/table/tng-table-sizing.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Directive,\n ElementRef,\n HostBinding,\n HostListener,\n type OnDestroy,\n type OnInit,\n booleanAttribute,\n forwardRef,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { TngTable, TngTableCell, TngTableHeaderCell } from './tng-table';\n\nexport type TngTableColumnWidthMap = Readonly<Record<string, string>>;\n\nfunction normalizeCssLength(value: unknown): string | null {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value !== 'string') {\n return null;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeOptionalString(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction normalizeWidthMap(value: unknown): Record<string, string> {\n if (typeof value !== 'object' || value === null) {\n return {};\n }\n\n const nextWidths: Record<string, string> = {};\n for (const [columnId, columnWidth] of Object.entries(value as Record<string, unknown>)) {\n const normalizedWidth = normalizeCssLength(columnWidth);\n if (normalizedWidth !== null) {\n nextWidths[columnId] = normalizedWidth;\n }\n }\n\n return nextWidths;\n}\n\nfunction parsePixelLength(value: string | null): number | null {\n if (value === null) {\n return null;\n }\n\n const trimmed = value.trim();\n if (/^-?\\d+(\\.\\d+)?px$/u.test(trimmed)) {\n return Number.parseFloat(trimmed.slice(0, -2));\n }\n\n if (/^-?\\d+(\\.\\d+)?$/u.test(trimmed)) {\n return Number.parseFloat(trimmed);\n }\n\n return null;\n}\n\nfunction measureWidth(element: HTMLElement): number {\n const rectWidth = element.getBoundingClientRect().width;\n if (Number.isFinite(rectWidth) && rectWidth > 0) {\n return rectWidth;\n }\n\n return element.offsetWidth;\n}\n\n@Directive({\n selector: 'table[tngTable][tngTableColumnSizing]',\n exportAs: 'tngTableColumnSizing',\n})\nexport class TngTableColumnSizing {\n private readonly columns = new Set<TngTableColumn>();\n private readonly table = inject(TngTable);\n private uncontrolledWidths: Record<string, string> = {};\n private resizingColumnId: string | null = null;\n\n public readonly widths = input<Record<string, unknown> | null | undefined>(undefined, {\n alias: 'tngTableColumnWidths',\n });\n public readonly columnWidthsChange = output<TngTableColumnWidthMap>();\n\n @HostBinding('attr.data-column-sizing')\n protected readonly dataColumnSizing = '' as const;\n\n public getResolvedMaxWidth(column: TngTableColumn): string | null {\n const columnId = column.getColumnId();\n return columnId === null ? column.getMaxWidth() : this.resolveColumnMaxWidth(columnId);\n }\n\n public getResolvedMinWidth(column: TngTableColumn): string | null {\n const columnId = column.getColumnId();\n return columnId === null ? column.getMinWidth() : this.resolveColumnMinWidth(columnId);\n }\n\n public getResolvedWidth(column: TngTableColumn): string | null {\n const columnId = column.getColumnId();\n if (columnId === null) {\n return column.getDefaultWidth();\n }\n\n return this.clampWidthValue(\n this.getCurrentWidths()[columnId] ?? this.resolveColumnDefaultWidth(columnId) ?? column.getDefaultWidth(),\n columnId,\n );\n }\n\n public isResizing(columnId: string | null): boolean {\n return columnId !== null && this.resizingColumnId === columnId;\n }\n\n public registerColumn(column: TngTableColumn): void {\n this.columns.add(column);\n }\n\n public resize(columnId: string, startWidth: number, delta: number): void {\n const signedDelta = this.table.dir() === 'rtl' ? -delta : delta;\n const nextWidth = this.clampPixelWidth(columnId, startWidth + signedDelta);\n this.resizingColumnId = columnId;\n this.commit({\n ...this.getCurrentWidths(),\n [columnId]: `${nextWidth}px`,\n });\n }\n\n public resolveColumnPixelWidth(columnId: string): number {\n const resolvedWidth = this.clampWidthValue(\n this.getCurrentWidths()[columnId] ?? this.resolveColumnDefaultWidth(columnId),\n columnId,\n );\n const parsedWidth = parsePixelLength(resolvedWidth);\n if (parsedWidth !== null) {\n return parsedWidth;\n }\n\n const measuredWidth = this.resolveMeasuredWidth(columnId);\n return measuredWidth ?? 0;\n }\n\n public stopResize(): void {\n this.resizingColumnId = null;\n }\n\n public unregisterColumn(column: TngTableColumn): void {\n this.columns.delete(column);\n }\n\n private clampPixelWidth(columnId: string, width: number): number {\n const minWidth = parsePixelLength(this.resolveColumnMinWidth(columnId));\n const maxWidth = parsePixelLength(this.resolveColumnMaxWidth(columnId));\n let nextWidth = Math.max(0, width);\n\n if (minWidth !== null) {\n nextWidth = Math.max(nextWidth, minWidth);\n }\n\n if (maxWidth !== null) {\n nextWidth = Math.min(nextWidth, maxWidth);\n }\n\n return nextWidth;\n }\n\n private clampWidthValue(value: string | null, columnId: string): string | null {\n const parsedWidth = parsePixelLength(value);\n if (parsedWidth === null) {\n return value;\n }\n\n return `${this.clampPixelWidth(columnId, parsedWidth)}px`;\n }\n\n private commit(nextWidths: Record<string, string>): void {\n if (this.widths() === undefined) {\n this.uncontrolledWidths = nextWidths;\n }\n\n this.columnWidthsChange.emit(Object.freeze({ ...nextWidths }));\n }\n\n private getCurrentWidths(): Record<string, string> {\n return this.widths() === undefined ? this.uncontrolledWidths : normalizeWidthMap(this.widths());\n }\n\n private resolveColumnDefaultWidth(columnId: string): string | null {\n return this.findColumnsById(columnId)\n .map((column) => column.getDefaultWidth())\n .find((width): width is string => width !== null) ?? null;\n }\n\n private resolveColumnMaxWidth(columnId: string): string | null {\n const widths = this.findColumnsById(columnId)\n .map((column) => column.getMaxWidth())\n .filter((width): width is string => width !== null);\n if (widths.length === 0) {\n return null;\n }\n\n const pixelWidths = widths\n .map((width) => parsePixelLength(width))\n .filter((width): width is number => width !== null);\n if (pixelWidths.length === widths.length) {\n return `${Math.min(...pixelWidths)}px`;\n }\n\n return widths[0] ?? null;\n }\n\n private resolveColumnMinWidth(columnId: string): string | null {\n const widths = this.findColumnsById(columnId)\n .map((column) => column.getMinWidth())\n .filter((width): width is string => width !== null);\n if (widths.length === 0) {\n return null;\n }\n\n const pixelWidths = widths\n .map((width) => parsePixelLength(width))\n .filter((width): width is number => width !== null);\n if (pixelWidths.length === widths.length) {\n return `${Math.max(...pixelWidths)}px`;\n }\n\n return widths[0] ?? null;\n }\n\n private resolveMeasuredWidth(columnId: string): number | null {\n const elements = this.findColumnsById(columnId).map((column) => column.getHostElement());\n if (elements.length === 0) {\n return null;\n }\n\n return elements.reduce((maxWidth, element) => Math.max(maxWidth, measureWidth(element)), 0);\n }\n\n private findColumnsById(columnId: string): readonly TngTableColumn[] {\n return [...this.columns].filter((column) => column.getColumnId() === columnId);\n }\n}\n\n@Directive({\n selector: 'th[tngTableColumn],td[tngTableColumn]',\n exportAs: 'tngTableColumn',\n})\nexport class TngTableColumn implements OnDestroy, OnInit {\n private readonly cell = inject(TngTableCell, {\n optional: true,\n });\n private readonly headerCell = inject(TngTableHeaderCell, {\n optional: true,\n });\n private readonly hostRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly sizing = inject(forwardRef(() => TngTableColumnSizing), {\n optional: true,\n }) as TngTableColumnSizing | null;\n\n public readonly columnId = input<string | null, unknown>(null, {\n alias: 'tngTableColumn',\n transform: normalizeOptionalString,\n });\n public readonly defaultWidth = input<string | null, unknown>(null, {\n alias: 'tngTableColumnWidth',\n transform: normalizeCssLength,\n });\n public readonly minWidth = input<string | null, unknown>(null, {\n alias: 'tngTableColumnMinWidth',\n transform: normalizeCssLength,\n });\n public readonly maxWidth = input<string | null, unknown>(null, {\n alias: 'tngTableColumnMaxWidth',\n transform: normalizeCssLength,\n });\n\n @HostBinding('attr.data-column-id')\n protected get dataColumnIdAttr(): string | null {\n return this.getColumnId();\n }\n\n @HostBinding('attr.data-column-max-width')\n protected get dataColumnMaxWidthAttr(): string | null {\n return this.getMaxWidth();\n }\n\n @HostBinding('attr.data-column-min-width')\n protected get dataColumnMinWidthAttr(): string | null {\n return this.getMinWidth();\n }\n\n @HostBinding('attr.data-column-width')\n protected get dataColumnWidthAttr(): string | null {\n return this.getDefaultWidth();\n }\n\n @HostBinding('style.max-width')\n protected get maxWidthAttr(): string | null {\n return this.sizing?.getResolvedMaxWidth(this) ?? this.getMaxWidth();\n }\n\n @HostBinding('style.min-width')\n protected get minWidthAttr(): string | null {\n return this.sizing?.getResolvedMinWidth(this) ?? this.getMinWidth();\n }\n\n @HostBinding('style.width')\n protected get widthAttr(): string | null {\n return this.sizing?.getResolvedWidth(this) ?? this.getDefaultWidth();\n }\n\n public ngOnDestroy(): void {\n this.sizing?.unregisterColumn(this);\n }\n\n public ngOnInit(): void {\n this.sizing?.registerColumn(this);\n }\n\n public getColumnId(): string | null {\n return this.columnId() ?? this.headerCell?.columnId() ?? this.cell?.columnId() ?? null;\n }\n\n public getDefaultWidth(): string | null {\n return this.defaultWidth();\n }\n\n public getHostElement(): HTMLElement {\n return this.hostRef.nativeElement;\n }\n\n public getMaxWidth(): string | null {\n return this.maxWidth();\n }\n\n public getMinWidth(): string | null {\n return this.minWidth();\n }\n}\n\n@Directive({\n selector: '[tngTableColumnResizer]',\n exportAs: 'tngTableColumnResizer',\n})\nexport class TngTableColumnResizer implements OnDestroy {\n private readonly sizing = inject(TngTableColumnSizing, {\n optional: true,\n });\n private activeResize: Readonly<{\n columnId: string;\n startClientX: number;\n startWidth: number;\n }> | null = null;\n\n public readonly columnId = input<string | null, unknown>(null, {\n alias: 'tngTableColumnResizer',\n transform: normalizeOptionalString,\n });\n public readonly disabled = input<boolean, boolean | string>(false, {\n alias: 'tngTableColumnResizerDisabled',\n transform: booleanAttribute,\n });\n\n @HostBinding('attr.aria-orientation')\n protected readonly ariaOrientation = 'vertical' as const;\n\n @HostBinding('attr.data-resizing')\n protected get dataResizingAttr(): '' | null {\n return this.sizing?.isResizing(this.columnId()) === true ? '' : null;\n }\n\n @HostBinding('attr.data-slot')\n protected readonly dataSlot = 'table-column-resizer' as const;\n\n @HostBinding('style.cursor')\n protected readonly cursor = 'col-resize' as const;\n\n public ngOnDestroy(): void {\n this.activeResize = null;\n this.sizing?.stopResize();\n }\n\n @HostListener('document:mousemove', ['$event'])\n protected onDocumentMouseMove(event: MouseEvent): void {\n if (this.activeResize === null) {\n return;\n }\n\n event.preventDefault();\n this.sizing?.resize(\n this.activeResize.columnId,\n this.activeResize.startWidth,\n event.clientX - this.activeResize.startClientX,\n );\n }\n\n @HostListener('document:mouseup')\n protected onDocumentMouseUp(): void {\n this.activeResize = null;\n this.sizing?.stopResize();\n }\n\n @HostListener('mousedown', ['$event'])\n protected onMouseDown(event: MouseEvent): void {\n const columnId = this.columnId();\n if (\n event.button !== 0\n || this.disabled()\n || this.sizing === null\n || columnId === null\n ) {\n return;\n }\n\n event.preventDefault();\n this.activeResize = Object.freeze({\n columnId,\n startClientX: event.clientX,\n startWidth: this.sizing.resolveColumnPixelWidth(columnId),\n });\n }\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import type { OnDestroy, OnInit } from '@angular/core';
2
+ import { type TngTableAriaSort, type TngTableSortDirection, type TngTableSortState } from '@tailng-ui/cdk';
3
+ import * as i0 from "@angular/core";
4
+ export type TngTableSortChange = Readonly<{
5
+ activeColumnId: string | null;
6
+ direction: TngTableSortDirection | null;
7
+ }>;
8
+ type TngSortHeaderKeydownEvent = Readonly<Pick<KeyboardEvent, 'key' | 'preventDefault'>>;
9
+ export declare class TngTableSort {
10
+ private readonly registeredHeaderIds;
11
+ private uncontrolledActiveColumnId;
12
+ private uncontrolledDirection;
13
+ readonly activeColumnId: import("@angular/core").InputSignal<string | null | undefined>;
14
+ readonly direction: import("@angular/core").InputSignalWithTransform<TngTableSortDirection | null | undefined, unknown>;
15
+ readonly disableClear: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
16
+ readonly sortChange: import("@angular/core").OutputEmitterRef<Readonly<{
17
+ activeColumnId: string | null;
18
+ direction: TngTableSortDirection | null;
19
+ }>>;
20
+ protected readonly dataSortable: "";
21
+ protected get dataSortColumnAttr(): string | null;
22
+ protected get dataSortDirectionAttr(): TngTableSortDirection | null;
23
+ getAriaSort(columnId: string): TngTableAriaSort;
24
+ getDirectionFor(columnId: string): TngTableSortDirection | null;
25
+ getState(): TngTableSortState<string>;
26
+ hasHeader(columnId: string): boolean;
27
+ registerHeader(columnId: string): void;
28
+ set(activeColumnId: string | null, direction: TngTableSortDirection | null): TngTableSortState<string>;
29
+ toggle(columnId: string): TngTableSortState<string>;
30
+ unregisterHeader(columnId: string): void;
31
+ private commit;
32
+ private createController;
33
+ static ɵfac: i0.ɵɵFactoryDeclaration<TngTableSort, never>;
34
+ static ɵdir: i0.ɵɵDirectiveDeclaration<TngTableSort, "[tngTableSort]", ["tngTableSort"], { "activeColumnId": { "alias": "tngTableSortActive"; "required": false; "isSignal": true; }; "direction": { "alias": "tngTableSortDirection"; "required": false; "isSignal": true; }; "disableClear": { "alias": "tngTableSortDisableClear"; "required": false; "isSignal": true; }; }, { "sortChange": "sortChange"; }, never, never, true, never>;
35
+ }
36
+ export declare class TngSortHeader implements OnDestroy, OnInit {
37
+ private readonly sort;
38
+ readonly columnId: import("@angular/core").InputSignal<string>;
39
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, string | boolean>;
40
+ protected get ariaSortAttr(): TngTableAriaSort | null;
41
+ protected readonly dataSlot: "table-sort-header";
42
+ protected get dataSortActiveAttr(): '' | null;
43
+ protected get dataSortDirectionAttr(): TngTableSortDirection | null;
44
+ ngOnDestroy(): void;
45
+ ngOnInit(): void;
46
+ protected onClick(): void;
47
+ protected onKeydown(event: TngSortHeaderKeydownEvent): void;
48
+ private toggle;
49
+ static ɵfac: i0.ɵɵFactoryDeclaration<TngSortHeader, never>;
50
+ static ɵdir: i0.ɵɵDirectiveDeclaration<TngSortHeader, "th[tngSortHeader]", ["tngSortHeader"], { "columnId": { "alias": "tngSortHeader"; "required": true; "isSignal": true; }; "disabled": { "alias": "tngSortHeaderDisabled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=tng-table-sort.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tng-table-sort.d.ts","sourceRoot":"","sources":["../../../../../../../../libs/tailng-ui/primitives/src/lib/layout/table/tng-table-sort.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACvB,MAAM,gBAAgB,CAAC;;AAExB,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,qBAAqB,GAAG,IAAI,CAAC;CACzC,CAAC,CAAC;AAEH,KAAK,yBAAyB,GAAG,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,GAAG,gBAAgB,CAAC,CAAC,CAAC;AAUzF,qBAIa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,0BAA0B,CAAuB;IACzD,OAAO,CAAC,qBAAqB,CAAsC;IAEnE,SAAgB,cAAc,iEAE3B;IACH,SAAgB,SAAS,sGAGtB;IACH,SAAgB,YAAY,8EAGzB;IAEH,SAAgB,UAAU;wBAnCV,MAAM,GAAG,IAAI;mBAClB,qBAAqB,GAAG,IAAI;QAkCmB;IAG1D,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAG,EAAE,CAAU;IAG9C,SAAS,KAAK,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAEhD;IAGD,SAAS,KAAK,qBAAqB,IAAI,qBAAqB,GAAG,IAAI,CAElE;IAEM,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB;IAI/C,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB,GAAG,IAAI;IAS/D,QAAQ,IAAI,iBAAiB,CAAC,MAAM,CAAC;IAQrC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIpC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAItC,GAAG,CACR,cAAc,EAAE,MAAM,GAAG,IAAI,EAC7B,SAAS,EAAE,qBAAqB,GAAG,IAAI,GACtC,iBAAiB,CAAC,MAAM,CAAC;IAIrB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC;IAInD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAI/C,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,gBAAgB;yCA7Fb,YAAY;2CAAZ,YAAY;CAsGxB;AAED,qBAIa,aAAc,YAAW,SAAS,EAAE,MAAM;IACrD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4C;IAEjE,SAAgB,QAAQ,8CAErB;IACH,SAAgB,QAAQ,8EAGrB;IAGH,SAAS,KAAK,YAAY,IAAI,gBAAgB,GAAG,IAAI,CAMpD;IAGD,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAG,mBAAmB,CAAU;IAG3D,SAAS,KAAK,kBAAkB,IAAI,EAAE,GAAG,IAAI,CAE5C;IAGD,SAAS,KAAK,qBAAqB,IAAI,qBAAqB,GAAG,IAAI,CAElE;IAEM,WAAW,IAAI,IAAI;IAInB,QAAQ,IAAI,IAAI;IAKvB,SAAS,CAAC,OAAO,IAAI,IAAI;IAKzB,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,yBAAyB,GAAG,IAAI;IAS3D,OAAO,CAAC,MAAM;yCAxDH,aAAa;2CAAb,aAAa;CA+DzB"}
@@ -0,0 +1,167 @@
1
+ import { Directive, HostBinding, HostListener, booleanAttribute, inject, input, output, } from '@angular/core';
2
+ import { createTngSortController, } from '@tailng-ui/cdk';
3
+ import * as i0 from "@angular/core";
4
+ function normalizeSortDirection(value) {
5
+ if (value === 'asc' || value === 'desc') {
6
+ return value;
7
+ }
8
+ return null;
9
+ }
10
+ export class TngTableSort {
11
+ registeredHeaderIds = new Set();
12
+ uncontrolledActiveColumnId = null;
13
+ uncontrolledDirection = null;
14
+ activeColumnId = input(undefined, { ...(ngDevMode ? { debugName: "activeColumnId" } : {}), alias: 'tngTableSortActive' });
15
+ direction = input(undefined, { ...(ngDevMode ? { debugName: "direction" } : {}), alias: 'tngTableSortDirection',
16
+ transform: normalizeSortDirection });
17
+ disableClear = input(false, { ...(ngDevMode ? { debugName: "disableClear" } : {}), alias: 'tngTableSortDisableClear',
18
+ transform: booleanAttribute });
19
+ sortChange = output();
20
+ dataSortable = '';
21
+ get dataSortColumnAttr() {
22
+ return this.getState().activeColumnId;
23
+ }
24
+ get dataSortDirectionAttr() {
25
+ return this.getState().direction;
26
+ }
27
+ getAriaSort(columnId) {
28
+ return this.createController().getAriaSort(columnId);
29
+ }
30
+ getDirectionFor(columnId) {
31
+ const state = this.getState();
32
+ if (state.activeColumnId !== columnId) {
33
+ return null;
34
+ }
35
+ return state.direction;
36
+ }
37
+ getState() {
38
+ return Object.freeze({
39
+ activeColumnId: this.activeColumnId() ?? this.uncontrolledActiveColumnId,
40
+ direction: this.direction() ?? this.uncontrolledDirection,
41
+ disableClear: this.disableClear(),
42
+ });
43
+ }
44
+ hasHeader(columnId) {
45
+ return this.registeredHeaderIds.has(columnId);
46
+ }
47
+ registerHeader(columnId) {
48
+ this.registeredHeaderIds.add(columnId);
49
+ }
50
+ set(activeColumnId, direction) {
51
+ return this.commit(this.createController().set(activeColumnId, direction));
52
+ }
53
+ toggle(columnId) {
54
+ return this.commit(this.createController().toggle(columnId));
55
+ }
56
+ unregisterHeader(columnId) {
57
+ this.registeredHeaderIds.delete(columnId);
58
+ }
59
+ commit(nextState) {
60
+ if (this.activeColumnId() === undefined) {
61
+ this.uncontrolledActiveColumnId = nextState.activeColumnId;
62
+ }
63
+ if (this.direction() === undefined) {
64
+ this.uncontrolledDirection = nextState.direction;
65
+ }
66
+ this.sortChange.emit({
67
+ activeColumnId: nextState.activeColumnId,
68
+ direction: nextState.direction,
69
+ });
70
+ return this.getState();
71
+ }
72
+ createController() {
73
+ const state = this.getState();
74
+ return createTngSortController({
75
+ activeColumnId: state.activeColumnId,
76
+ direction: state.direction,
77
+ disableClear: state.disableClear,
78
+ });
79
+ }
80
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableSort, deps: [], target: i0.ɵɵFactoryTarget.Directive });
81
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngTableSort, isStandalone: true, selector: "[tngTableSort]", inputs: { activeColumnId: { classPropertyName: "activeColumnId", publicName: "tngTableSortActive", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "tngTableSortDirection", isSignal: true, isRequired: false, transformFunction: null }, disableClear: { classPropertyName: "disableClear", publicName: "tngTableSortDisableClear", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortChange: "sortChange" }, host: { properties: { "attr.data-sortable": "this.dataSortable", "attr.data-sort-column": "this.dataSortColumnAttr", "attr.data-sort-direction": "this.dataSortDirectionAttr" } }, exportAs: ["tngTableSort"], ngImport: i0 });
82
+ }
83
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngTableSort, decorators: [{
84
+ type: Directive,
85
+ args: [{
86
+ selector: '[tngTableSort]',
87
+ exportAs: 'tngTableSort',
88
+ }]
89
+ }], propDecorators: { activeColumnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableSortActive", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableSortDirection", required: false }] }], disableClear: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngTableSortDisableClear", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }], dataSortable: [{
90
+ type: HostBinding,
91
+ args: ['attr.data-sortable']
92
+ }], dataSortColumnAttr: [{
93
+ type: HostBinding,
94
+ args: ['attr.data-sort-column']
95
+ }], dataSortDirectionAttr: [{
96
+ type: HostBinding,
97
+ args: ['attr.data-sort-direction']
98
+ }] } });
99
+ export class TngSortHeader {
100
+ sort = inject(TngTableSort, { optional: true });
101
+ columnId = input.required({ ...(ngDevMode ? { debugName: "columnId" } : {}), alias: 'tngSortHeader' });
102
+ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : {}), alias: 'tngSortHeaderDisabled',
103
+ transform: booleanAttribute });
104
+ get ariaSortAttr() {
105
+ if (this.sort === null) {
106
+ return null;
107
+ }
108
+ return this.sort.getAriaSort(this.columnId());
109
+ }
110
+ dataSlot = 'table-sort-header';
111
+ get dataSortActiveAttr() {
112
+ return this.sort?.getDirectionFor(this.columnId()) !== null ? '' : null;
113
+ }
114
+ get dataSortDirectionAttr() {
115
+ return this.sort?.getDirectionFor(this.columnId()) ?? null;
116
+ }
117
+ ngOnDestroy() {
118
+ this.sort?.unregisterHeader(this.columnId());
119
+ }
120
+ ngOnInit() {
121
+ this.sort?.registerHeader(this.columnId());
122
+ }
123
+ onClick() {
124
+ this.toggle();
125
+ }
126
+ onKeydown(event) {
127
+ if (event.key !== 'Enter' && event.key !== ' ') {
128
+ return;
129
+ }
130
+ event.preventDefault();
131
+ this.toggle();
132
+ }
133
+ toggle() {
134
+ if (this.disabled() || this.sort === null) {
135
+ return;
136
+ }
137
+ this.sort.toggle(this.columnId());
138
+ }
139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngSortHeader, deps: [], target: i0.ɵɵFactoryTarget.Directive });
140
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.1.1", type: TngSortHeader, isStandalone: true, selector: "th[tngSortHeader]", inputs: { columnId: { classPropertyName: "columnId", publicName: "tngSortHeader", isSignal: true, isRequired: true, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "tngSortHeaderDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown": "onKeydown($event)" }, properties: { "attr.aria-sort": "this.ariaSortAttr", "attr.data-slot": "this.dataSlot", "attr.data-sort-active": "this.dataSortActiveAttr", "attr.data-sort-direction": "this.dataSortDirectionAttr" } }, exportAs: ["tngSortHeader"], ngImport: i0 });
141
+ }
142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: TngSortHeader, decorators: [{
143
+ type: Directive,
144
+ args: [{
145
+ selector: 'th[tngSortHeader]',
146
+ exportAs: 'tngSortHeader',
147
+ }]
148
+ }], propDecorators: { columnId: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngSortHeader", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "tngSortHeaderDisabled", required: false }] }], ariaSortAttr: [{
149
+ type: HostBinding,
150
+ args: ['attr.aria-sort']
151
+ }], dataSlot: [{
152
+ type: HostBinding,
153
+ args: ['attr.data-slot']
154
+ }], dataSortActiveAttr: [{
155
+ type: HostBinding,
156
+ args: ['attr.data-sort-active']
157
+ }], dataSortDirectionAttr: [{
158
+ type: HostBinding,
159
+ args: ['attr.data-sort-direction']
160
+ }], onClick: [{
161
+ type: HostListener,
162
+ args: ['click']
163
+ }], onKeydown: [{
164
+ type: HostListener,
165
+ args: ['keydown', ['$event']]
166
+ }] } });
167
+ //# sourceMappingURL=tng-table-sort.js.map