ngx-com 0.0.19 → 0.0.21

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 (56) hide show
  1. package/fesm2022/ngx-com-components-alert.mjs +346 -0
  2. package/fesm2022/ngx-com-components-alert.mjs.map +1 -0
  3. package/fesm2022/ngx-com-components-button.mjs +1 -1
  4. package/fesm2022/ngx-com-components-button.mjs.map +1 -1
  5. package/fesm2022/ngx-com-components-calendar.mjs +29 -36
  6. package/fesm2022/ngx-com-components-calendar.mjs.map +1 -1
  7. package/fesm2022/ngx-com-components-card.mjs +1 -1
  8. package/fesm2022/ngx-com-components-card.mjs.map +1 -1
  9. package/fesm2022/ngx-com-components-carousel.mjs +708 -0
  10. package/fesm2022/ngx-com-components-carousel.mjs.map +1 -0
  11. package/fesm2022/ngx-com-components-checkbox.mjs +17 -8
  12. package/fesm2022/ngx-com-components-checkbox.mjs.map +1 -1
  13. package/fesm2022/ngx-com-components-code-block.mjs +158 -0
  14. package/fesm2022/ngx-com-components-code-block.mjs.map +1 -0
  15. package/fesm2022/ngx-com-components-collapsible.mjs +1 -1
  16. package/fesm2022/ngx-com-components-collapsible.mjs.map +1 -1
  17. package/fesm2022/ngx-com-components-confirm.mjs +3 -3
  18. package/fesm2022/ngx-com-components-confirm.mjs.map +1 -1
  19. package/fesm2022/ngx-com-components-dialog.mjs +703 -0
  20. package/fesm2022/ngx-com-components-dialog.mjs.map +1 -0
  21. package/fesm2022/ngx-com-components-dropdown.mjs +36 -31
  22. package/fesm2022/ngx-com-components-dropdown.mjs.map +1 -1
  23. package/fesm2022/ngx-com-components-form-field.mjs +48 -8
  24. package/fesm2022/ngx-com-components-form-field.mjs.map +1 -1
  25. package/fesm2022/ngx-com-components-item.mjs +1 -1
  26. package/fesm2022/ngx-com-components-item.mjs.map +1 -1
  27. package/fesm2022/ngx-com-components-paginator.mjs +3 -3
  28. package/fesm2022/ngx-com-components-paginator.mjs.map +1 -1
  29. package/fesm2022/ngx-com-components-radio.mjs +16 -9
  30. package/fesm2022/ngx-com-components-radio.mjs.map +1 -1
  31. package/fesm2022/ngx-com-components-segmented-control.mjs +1 -1
  32. package/fesm2022/ngx-com-components-segmented-control.mjs.map +1 -1
  33. package/fesm2022/ngx-com-components-separator.mjs +102 -0
  34. package/fesm2022/ngx-com-components-separator.mjs.map +1 -0
  35. package/fesm2022/ngx-com-components-switch.mjs +258 -0
  36. package/fesm2022/ngx-com-components-switch.mjs.map +1 -0
  37. package/fesm2022/ngx-com-components-table.mjs +631 -0
  38. package/fesm2022/ngx-com-components-table.mjs.map +1 -0
  39. package/fesm2022/ngx-com-components-tabs.mjs +2 -2
  40. package/fesm2022/ngx-com-components-tabs.mjs.map +1 -1
  41. package/fesm2022/ngx-com-components-toast.mjs +783 -0
  42. package/fesm2022/ngx-com-components-toast.mjs.map +1 -0
  43. package/package.json +33 -1
  44. package/types/ngx-com-components-alert.d.ts +166 -0
  45. package/types/ngx-com-components-carousel.d.ts +281 -0
  46. package/types/ngx-com-components-checkbox.d.ts +7 -2
  47. package/types/ngx-com-components-code-block.d.ts +66 -0
  48. package/types/ngx-com-components-confirm.d.ts +2 -2
  49. package/types/ngx-com-components-dialog.d.ts +264 -0
  50. package/types/ngx-com-components-dropdown.d.ts +8 -5
  51. package/types/ngx-com-components-form-field.d.ts +19 -3
  52. package/types/ngx-com-components-radio.d.ts +5 -3
  53. package/types/ngx-com-components-separator.d.ts +75 -0
  54. package/types/ngx-com-components-switch.d.ts +110 -0
  55. package/types/ngx-com-components-table.d.ts +377 -0
  56. package/types/ngx-com-components-toast.d.ts +217 -0
@@ -0,0 +1,631 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, TemplateRef, Directive, input, contentChild, booleanAttribute, signal, DestroyRef, contentChildren, computed, ViewEncapsulation, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import { ComSpinner } from 'ngx-com/components/spinner';
5
+ import { cva } from 'class-variance-authority';
6
+
7
+ /**
8
+ * Structural directive that captures the template for a header cell.
9
+ *
10
+ * Use with the star syntax inside a `comColumnDef` container.
11
+ *
12
+ * @example
13
+ * ```html
14
+ * <ng-container comColumnDef="name">
15
+ * <th *comHeaderCellDef>Name</th>
16
+ * <td *comCellDef="let row">{{ row.name }}</td>
17
+ * </ng-container>
18
+ * ```
19
+ */
20
+ class ComHeaderCellDef {
21
+ templateRef = inject((TemplateRef));
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComHeaderCellDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
23
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: ComHeaderCellDef, isStandalone: true, selector: "[comHeaderCellDef]", ngImport: i0 });
24
+ }
25
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComHeaderCellDef, decorators: [{
26
+ type: Directive,
27
+ args: [{
28
+ selector: '[comHeaderCellDef]',
29
+ }]
30
+ }] });
31
+
32
+ /**
33
+ * Structural directive that captures the template for a body cell.
34
+ *
35
+ * Use with the star syntax inside a `comColumnDef` container.
36
+ *
37
+ * @example
38
+ * ```html
39
+ * <ng-container comColumnDef="name">
40
+ * <th *comHeaderCellDef>Name</th>
41
+ * <td *comCellDef="let row">{{ row.name }}</td>
42
+ * </ng-container>
43
+ * ```
44
+ */
45
+ class ComCellDef {
46
+ templateRef = inject((TemplateRef));
47
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComCellDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
48
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: ComCellDef, isStandalone: true, selector: "[comCellDef]", ngImport: i0 });
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComCellDef, decorators: [{
51
+ type: Directive,
52
+ args: [{
53
+ selector: '[comCellDef]',
54
+ }]
55
+ }] });
56
+
57
+ /**
58
+ * Structural directive that captures the template for a footer cell.
59
+ *
60
+ * Use with the star syntax inside a `comColumnDef` container.
61
+ *
62
+ * @example
63
+ * ```html
64
+ * <ng-container comColumnDef="amount">
65
+ * <th *comHeaderCellDef>Amount</th>
66
+ * <td *comCellDef="let row">{{ row.amount | currency }}</td>
67
+ * <td *comFooterCellDef>{{ total() | currency }}</td>
68
+ * </ng-container>
69
+ * ```
70
+ */
71
+ class ComFooterCellDef {
72
+ templateRef = inject((TemplateRef));
73
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComFooterCellDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
74
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: ComFooterCellDef, isStandalone: true, selector: "[comFooterCellDef]", ngImport: i0 });
75
+ }
76
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComFooterCellDef, decorators: [{
77
+ type: Directive,
78
+ args: [{
79
+ selector: '[comFooterCellDef]',
80
+ }]
81
+ }] });
82
+
83
+ /**
84
+ * Defines a single column in a `com-table`.
85
+ *
86
+ * Contains a header cell template, a body cell template, and an optional footer cell template.
87
+ *
88
+ * @example
89
+ * ```html
90
+ * <ng-container comColumnDef="name">
91
+ * <th *comHeaderCellDef>Name</th>
92
+ * <td *comCellDef="let row">{{ row.name }}</td>
93
+ * </ng-container>
94
+ * ```
95
+ */
96
+ class ComColumnDef {
97
+ /** The column name — used to match header/row column lists. */
98
+ name = input.required({ ...(ngDevMode ? { debugName: "name" } : {}), alias: 'comColumnDef' });
99
+ /** @internal Header cell template for this column. */
100
+ headerCellDef = contentChild(ComHeaderCellDef, ...(ngDevMode ? [{ debugName: "headerCellDef" }] : []));
101
+ /** @internal Body cell template for this column. */
102
+ cellDef = contentChild(ComCellDef, ...(ngDevMode ? [{ debugName: "cellDef" }] : []));
103
+ /** @internal Optional footer cell template for this column. */
104
+ footerCellDef = contentChild(ComFooterCellDef, ...(ngDevMode ? [{ debugName: "footerCellDef" }] : []));
105
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComColumnDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
106
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "21.2.0", type: ComColumnDef, isStandalone: true, selector: "[comColumnDef]", inputs: { name: { classPropertyName: "name", publicName: "comColumnDef", isSignal: true, isRequired: true, transformFunction: null } }, queries: [{ propertyName: "headerCellDef", first: true, predicate: ComHeaderCellDef, descendants: true, isSignal: true }, { propertyName: "cellDef", first: true, predicate: ComCellDef, descendants: true, isSignal: true }, { propertyName: "footerCellDef", first: true, predicate: ComFooterCellDef, descendants: true, isSignal: true }], exportAs: ["comColumnDef"], ngImport: i0 });
107
+ }
108
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComColumnDef, decorators: [{
109
+ type: Directive,
110
+ args: [{
111
+ selector: '[comColumnDef]',
112
+ exportAs: 'comColumnDef',
113
+ }]
114
+ }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "comColumnDef", required: true }] }], headerCellDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComHeaderCellDef), { isSignal: true }] }], cellDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComCellDef), { isSignal: true }] }], footerCellDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComFooterCellDef), { isSignal: true }] }] } });
115
+
116
+ /**
117
+ * Defines which columns appear in the header row and their order.
118
+ *
119
+ * @example
120
+ * ```html
121
+ * <tr comHeaderRowDef="['name', 'email', 'role']"></tr>
122
+ * ```
123
+ *
124
+ * @example Sticky header row
125
+ * ```html
126
+ * <tr comHeaderRowDef="['name', 'email']" comHeaderRowDefSticky></tr>
127
+ * ```
128
+ */
129
+ class ComHeaderRowDef {
130
+ /** Ordered list of column names to display. */
131
+ columns = input.required({ ...(ngDevMode ? { debugName: "columns" } : {}), alias: 'comHeaderRowDef' });
132
+ /** Makes this header row sticky (alternative to table-level `stickyHeader`). */
133
+ sticky = input(false, { ...(ngDevMode ? { debugName: "sticky" } : {}), alias: 'comHeaderRowDefSticky',
134
+ transform: booleanAttribute });
135
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComHeaderRowDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
136
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: ComHeaderRowDef, isStandalone: true, selector: "[comHeaderRowDef]", inputs: { columns: { classPropertyName: "columns", publicName: "comHeaderRowDef", isSignal: true, isRequired: true, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "comHeaderRowDefSticky", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
137
+ }
138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComHeaderRowDef, decorators: [{
139
+ type: Directive,
140
+ args: [{
141
+ selector: '[comHeaderRowDef]',
142
+ }]
143
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "comHeaderRowDef", required: true }] }], sticky: [{ type: i0.Input, args: [{ isSignal: true, alias: "comHeaderRowDefSticky", required: false }] }] } });
144
+
145
+ /**
146
+ * Defines which columns appear in each body row and their order.
147
+ *
148
+ * @example
149
+ * ```html
150
+ * <tr comRowDef [comRowDefColumns]="['name', 'email', 'role']"></tr>
151
+ * ```
152
+ */
153
+ class ComRowDef {
154
+ /** Ordered list of column names to display per body row. */
155
+ columns = input.required({ ...(ngDevMode ? { debugName: "columns" } : {}), alias: 'comRowDefColumns' });
156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComRowDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
157
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: ComRowDef, isStandalone: true, selector: "[comRowDef]", inputs: { columns: { classPropertyName: "columns", publicName: "comRowDefColumns", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
158
+ }
159
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComRowDef, decorators: [{
160
+ type: Directive,
161
+ args: [{
162
+ selector: '[comRowDef]',
163
+ }]
164
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "comRowDefColumns", required: true }] }] } });
165
+
166
+ /**
167
+ * Defines which columns appear in the footer row and their order.
168
+ *
169
+ * @example
170
+ * ```html
171
+ * <tr comFooterRowDef="['description', 'amount']"></tr>
172
+ * ```
173
+ */
174
+ class ComFooterRowDef {
175
+ /** Ordered list of column names in the footer. */
176
+ columns = input.required({ ...(ngDevMode ? { debugName: "columns" } : {}), alias: 'comFooterRowDef' });
177
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComFooterRowDef, deps: [], target: i0.ɵɵFactoryTarget.Directive });
178
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: ComFooterRowDef, isStandalone: true, selector: "[comFooterRowDef]", inputs: { columns: { classPropertyName: "columns", publicName: "comFooterRowDef", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComFooterRowDef, decorators: [{
181
+ type: Directive,
182
+ args: [{
183
+ selector: '[comFooterRowDef]',
184
+ }]
185
+ }], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "comFooterRowDef", required: true }] }] } });
186
+
187
+ /**
188
+ * Structural directive for the empty-state row shown when the data source is empty.
189
+ *
190
+ * Place inside `com-table`. The template receives the column count for colspan.
191
+ *
192
+ * @example
193
+ * ```html
194
+ * <com-table [dataSource]="data()">
195
+ * <!-- column defs... -->
196
+ *
197
+ * <ng-template comNoDataRow>
198
+ * <td [attr.colspan]="displayedColumns().length" class="text-center py-8">
199
+ * No results found.
200
+ * </td>
201
+ * </ng-template>
202
+ * </com-table>
203
+ * ```
204
+ */
205
+ class ComNoDataRow {
206
+ templateRef = inject((TemplateRef));
207
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComNoDataRow, deps: [], target: i0.ɵɵFactoryTarget.Directive });
208
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.0", type: ComNoDataRow, isStandalone: true, selector: "[comNoDataRow]", ngImport: i0 });
209
+ }
210
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComNoDataRow, decorators: [{
211
+ type: Directive,
212
+ args: [{
213
+ selector: '[comNoDataRow]',
214
+ }]
215
+ }] });
216
+
217
+ /**
218
+ * Abstract data source for ComTable.
219
+ *
220
+ * Implement `connect()` to provide a signal of data, and `disconnect()` to clean up.
221
+ * The table calls `connect()` on init and `disconnect()` on destroy.
222
+ *
223
+ * @example Signal-based data source
224
+ * ```typescript
225
+ * class MyDataSource extends ComDataSource<User> {
226
+ * private readonly data = signal<User[]>([]);
227
+ *
228
+ * connect(): Signal<readonly User[]> {
229
+ * return this.data.asReadonly();
230
+ * }
231
+ *
232
+ * disconnect(): void {
233
+ * // cleanup if needed
234
+ * }
235
+ *
236
+ * setData(users: User[]): void {
237
+ * this.data.set(users);
238
+ * }
239
+ * }
240
+ * ```
241
+ */
242
+ class ComDataSource {
243
+ }
244
+ /**
245
+ * Simple array-backed data source.
246
+ *
247
+ * Wraps a plain array in a writable signal so it can be used with ComTable's DataSource API.
248
+ */
249
+ class ComArrayDataSource extends ComDataSource {
250
+ data = signal([], ...(ngDevMode ? [{ debugName: "data" }] : []));
251
+ constructor(initialData = []) {
252
+ super();
253
+ this.data.set(initialData);
254
+ }
255
+ connect() {
256
+ return this.data.asReadonly();
257
+ }
258
+ disconnect() {
259
+ // No cleanup needed for a simple array
260
+ }
261
+ /** Replace the entire data set. */
262
+ setData(data) {
263
+ this.data.set(data);
264
+ }
265
+ }
266
+ /**
267
+ * Type guard to check if a value is a ComDataSource instance.
268
+ */
269
+ function isDataSource(value) {
270
+ return value instanceof ComDataSource;
271
+ }
272
+
273
+ /**
274
+ * CVA variants for the table container wrapper.
275
+ */
276
+ const tableContainerVariants = cva('relative overflow-x-auto');
277
+ /**
278
+ * CVA variants for the `<table>` element.
279
+ *
280
+ * @tokens `--color-foreground`
281
+ */
282
+ const tableVariants = cva('w-full caption-bottom text-sm text-foreground');
283
+ /**
284
+ * CVA variants for the `<thead>` element.
285
+ *
286
+ * @tokens `--color-background`
287
+ */
288
+ const tableHeaderVariants = cva('', {
289
+ variants: {
290
+ sticky: {
291
+ true: 'sticky top-0 z-10 bg-background',
292
+ false: '',
293
+ },
294
+ },
295
+ defaultVariants: {
296
+ sticky: false,
297
+ },
298
+ });
299
+ /**
300
+ * CVA variants for `<th>` header cells.
301
+ *
302
+ * @tokens `--color-muted-foreground`
303
+ */
304
+ const tableHeaderCellVariants = cva('text-left align-middle font-medium text-muted-foreground [&:has([comSortHeader])]:cursor-pointer', {
305
+ variants: {
306
+ density: {
307
+ compact: 'h-8 px-3 text-xs',
308
+ default: 'h-10 px-4 text-xs',
309
+ comfortable: 'h-12 px-5 text-sm',
310
+ },
311
+ },
312
+ defaultVariants: {
313
+ density: 'default',
314
+ },
315
+ });
316
+ /**
317
+ * CVA variants for `<tbody> <tr>` rows.
318
+ *
319
+ * @tokens `--color-border-subtle`, `--color-muted`, `--color-muted-hover`
320
+ */
321
+ const tableRowVariants = cva('transition-colors hover:bg-muted-hover', {
322
+ variants: {
323
+ variant: {
324
+ default: 'border-b border-border-subtle',
325
+ striped: 'border-b border-border-subtle even:bg-muted/50',
326
+ },
327
+ },
328
+ defaultVariants: {
329
+ variant: 'default',
330
+ },
331
+ });
332
+ /**
333
+ * CVA variants for `<td>` body cells.
334
+ */
335
+ const tableBodyCellVariants = cva('align-middle [&:has(com-checkbox)]:w-px', {
336
+ variants: {
337
+ density: {
338
+ compact: 'px-3 py-1.5',
339
+ default: 'px-4 py-2.5',
340
+ comfortable: 'px-5 py-3.5',
341
+ },
342
+ },
343
+ defaultVariants: {
344
+ density: 'default',
345
+ },
346
+ });
347
+ /**
348
+ * CVA variants for `<tfoot> <td>` footer cells.
349
+ *
350
+ * @tokens `--color-foreground`, `--color-border`
351
+ */
352
+ const tableFooterCellVariants = cva('align-middle font-medium text-foreground border-t border-border', {
353
+ variants: {
354
+ density: {
355
+ compact: 'h-8 px-3 text-xs',
356
+ default: 'h-10 px-4 text-sm',
357
+ comfortable: 'h-12 px-5 text-sm',
358
+ },
359
+ },
360
+ defaultVariants: {
361
+ density: 'default',
362
+ },
363
+ });
364
+
365
+ /**
366
+ * Declarative data table component using native HTML `<table>` semantics.
367
+ *
368
+ * Define columns via `comColumnDef` with `*comHeaderCellDef` and `*comCellDef`,
369
+ * then declare row structure via `comHeaderRowDef` and `comRowDef`.
370
+ *
371
+ * Accepts either a plain `T[]` or a `ComDataSource<T>` for the data source.
372
+ *
373
+ * @tokens `--color-background`, `--color-foreground`, `--color-muted`, `--color-muted-foreground`,
374
+ * `--color-muted-hover`, `--color-border`, `--color-border-subtle`
375
+ *
376
+ * @example Basic table
377
+ * ```html
378
+ * <com-table [dataSource]="users()">
379
+ * <ng-container comColumnDef="name">
380
+ * <th *comHeaderCellDef>Name</th>
381
+ * <td *comCellDef="let row">{{ row.name }}</td>
382
+ * </ng-container>
383
+ *
384
+ * <ng-container comColumnDef="email">
385
+ * <th *comHeaderCellDef>Email</th>
386
+ * <td *comCellDef="let row">{{ row.email }}</td>
387
+ * </ng-container>
388
+ *
389
+ * <tr comHeaderRowDef="['name', 'email']"></tr>
390
+ * <tr comRowDef [comRowDefColumns]="['name', 'email']"></tr>
391
+ * </com-table>
392
+ * ```
393
+ *
394
+ * @example With DataSource
395
+ * ```typescript
396
+ * class UserDataSource extends ComDataSource<User> {
397
+ * private data = signal<User[]>([]);
398
+ * connect() { return this.data.asReadonly(); }
399
+ * disconnect() {}
400
+ * setData(users: User[]) { this.data.set(users); }
401
+ * }
402
+ * ```
403
+ * ```html
404
+ * <com-table [dataSource]="userDataSource">
405
+ * ...
406
+ * </com-table>
407
+ * ```
408
+ */
409
+ class ComTable {
410
+ destroyRef = inject(DestroyRef);
411
+ // ─── Inputs ───
412
+ /** The data to render — accepts a plain array or a ComDataSource. */
413
+ dataSource = input([], ...(ngDevMode ? [{ debugName: "dataSource" }] : []));
414
+ /** Track function for `@for`. Defaults to tracking by index. */
415
+ trackByFn = input((index, _item) => index, ...(ngDevMode ? [{ debugName: "trackByFn" }] : []));
416
+ /** Visual treatment of body rows. */
417
+ variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : []));
418
+ /** Row height / cell padding. */
419
+ density = input('default', ...(ngDevMode ? [{ debugName: "density" }] : []));
420
+ /** Whether the header row sticks on scroll. */
421
+ stickyHeader = input(false, { ...(ngDevMode ? { debugName: "stickyHeader" } : {}), transform: booleanAttribute });
422
+ /** Shows a loading overlay with spinner. */
423
+ loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : {}), transform: booleanAttribute });
424
+ /** Accessible label for the table element. */
425
+ ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : []));
426
+ // ─── Content Queries ───
427
+ /** @internal All column definitions projected into the table. */
428
+ columnDefs = contentChildren(ComColumnDef, ...(ngDevMode ? [{ debugName: "columnDefs" }] : []));
429
+ /** @internal Header row definition. */
430
+ headerRowDef = contentChild(ComHeaderRowDef, ...(ngDevMode ? [{ debugName: "headerRowDef" }] : []));
431
+ /** @internal Body row definition. */
432
+ rowDef = contentChild(ComRowDef, ...(ngDevMode ? [{ debugName: "rowDef" }] : []));
433
+ /** @internal Optional footer row definition. */
434
+ footerRowDef = contentChild(ComFooterRowDef, ...(ngDevMode ? [{ debugName: "footerRowDef" }] : []));
435
+ /** @internal Optional no-data row template. */
436
+ noDataRow = contentChild(ComNoDataRow, ...(ngDevMode ? [{ debugName: "noDataRow" }] : []));
437
+ // ─── Derived State ───
438
+ /** @internal Map of column name → column definition for O(1) lookup. */
439
+ columnDefMap = computed(() => {
440
+ const map = new Map();
441
+ for (const col of this.columnDefs()) {
442
+ map.set(col.name(), col);
443
+ }
444
+ return map;
445
+ }, ...(ngDevMode ? [{ debugName: "columnDefMap" }] : []));
446
+ /** @internal Resolved render data — handles both array and DataSource inputs. */
447
+ dataSourceSignal = computed(() => {
448
+ const ds = this.dataSource();
449
+ if (isDataSource(ds)) {
450
+ return ds.connect();
451
+ }
452
+ return signal(ds);
453
+ }, ...(ngDevMode ? [{ debugName: "dataSourceSignal" }] : []));
454
+ /** @internal The actual data array to render. */
455
+ renderData = computed(() => this.dataSourceSignal()(), ...(ngDevMode ? [{ debugName: "renderData" }] : []));
456
+ /** @internal Header column names. */
457
+ headerColumns = computed(() => this.headerRowDef()?.columns() ?? [], ...(ngDevMode ? [{ debugName: "headerColumns" }] : []));
458
+ /** @internal Body column names. */
459
+ bodyColumns = computed(() => this.rowDef()?.columns() ?? this.headerColumns(), ...(ngDevMode ? [{ debugName: "bodyColumns" }] : []));
460
+ /** @internal Footer column names. */
461
+ footerColumns = computed(() => this.footerRowDef()?.columns() ?? [], ...(ngDevMode ? [{ debugName: "footerColumns" }] : []));
462
+ /** @internal Whether the header should be sticky. */
463
+ isSticky = computed(() => this.stickyHeader() || (this.headerRowDef()?.sticky() ?? false), ...(ngDevMode ? [{ debugName: "isSticky" }] : []));
464
+ // ─── CVA Classes ───
465
+ containerClasses = computed(() => tableContainerVariants(), ...(ngDevMode ? [{ debugName: "containerClasses" }] : []));
466
+ tableClasses = computed(() => tableVariants(), ...(ngDevMode ? [{ debugName: "tableClasses" }] : []));
467
+ theadClasses = computed(() => tableHeaderVariants({ sticky: this.isSticky() }), ...(ngDevMode ? [{ debugName: "theadClasses" }] : []));
468
+ thClasses = computed(() => tableHeaderCellVariants({ density: this.density() }), ...(ngDevMode ? [{ debugName: "thClasses" }] : []));
469
+ trClasses = computed(() => tableRowVariants({ variant: this.variant() }), ...(ngDevMode ? [{ debugName: "trClasses" }] : []));
470
+ tdClasses = computed(() => tableBodyCellVariants({ density: this.density() }), ...(ngDevMode ? [{ debugName: "tdClasses" }] : []));
471
+ tfootTdClasses = computed(() => tableFooterCellVariants({ density: this.density() }), ...(ngDevMode ? [{ debugName: "tfootTdClasses" }] : []));
472
+ constructor() {
473
+ // Disconnect DataSource on destroy
474
+ this.destroyRef.onDestroy(() => {
475
+ const ds = this.dataSource();
476
+ if (isDataSource(ds)) {
477
+ ds.disconnect();
478
+ }
479
+ });
480
+ }
481
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComTable, deps: [], target: i0.ɵɵFactoryTarget.Component });
482
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ComTable, isStandalone: true, selector: "com-table", inputs: { dataSource: { classPropertyName: "dataSource", publicName: "dataSource", isSignal: true, isRequired: false, transformFunction: null }, trackByFn: { classPropertyName: "trackByFn", publicName: "trackByFn", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, density: { classPropertyName: "density", publicName: "density", isSignal: true, isRequired: false, transformFunction: null }, stickyHeader: { classPropertyName: "stickyHeader", publicName: "stickyHeader", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block" }, queries: [{ propertyName: "columnDefs", predicate: ComColumnDef, isSignal: true }, { propertyName: "headerRowDef", first: true, predicate: ComHeaderRowDef, descendants: true, isSignal: true }, { propertyName: "rowDef", first: true, predicate: ComRowDef, descendants: true, isSignal: true }, { propertyName: "footerRowDef", first: true, predicate: ComFooterRowDef, descendants: true, isSignal: true }, { propertyName: "noDataRow", first: true, predicate: ComNoDataRow, descendants: true, isSignal: true }], exportAs: ["comTable"], ngImport: i0, template: `
483
+ <div [class]="containerClasses()">
484
+ <table [class]="tableClasses()" [attr.aria-label]="ariaLabel()" [attr.aria-busy]="loading() || null">
485
+ <thead [class]="theadClasses()">
486
+ <tr>
487
+ @for (colName of headerColumns(); track colName) {
488
+ @let colDef = columnDefMap().get(colName);
489
+ @if (colDef?.headerCellDef(); as headerDef) {
490
+ <th [class]="thClasses()" scope="col">
491
+ <ng-container [ngTemplateOutlet]="headerDef.templateRef" />
492
+ </th>
493
+ }
494
+ }
495
+ </tr>
496
+ </thead>
497
+
498
+ <tbody>
499
+ @if (!loading() && renderData().length === 0 && noDataRow()) {
500
+ <tr>
501
+ <ng-container [ngTemplateOutlet]="noDataRow()!.templateRef" />
502
+ </tr>
503
+ } @else {
504
+ @for (row of renderData(); track trackByFn()($index, row); let idx = $index) {
505
+ <tr [class]="trClasses()">
506
+ @for (colName of bodyColumns(); track colName) {
507
+ @let colDef = columnDefMap().get(colName);
508
+ @if (colDef?.cellDef(); as cellDef) {
509
+ <td [class]="tdClasses()">
510
+ <ng-container
511
+ [ngTemplateOutlet]="cellDef.templateRef"
512
+ [ngTemplateOutletContext]="{ $implicit: row, index: idx }"
513
+ />
514
+ </td>
515
+ }
516
+ }
517
+ </tr>
518
+ }
519
+ }
520
+ </tbody>
521
+
522
+ @if (footerRowDef()) {
523
+ <tfoot>
524
+ <tr>
525
+ @for (colName of footerColumns(); track colName) {
526
+ @let colDef = columnDefMap().get(colName);
527
+ @if (colDef?.footerCellDef(); as footerDef) {
528
+ <td [class]="tfootTdClasses()">
529
+ <ng-container [ngTemplateOutlet]="footerDef.templateRef" />
530
+ </td>
531
+ }
532
+ }
533
+ </tr>
534
+ </tfoot>
535
+ }
536
+ </table>
537
+
538
+ @if (loading()) {
539
+ <div class="absolute inset-0 flex items-center justify-center bg-background/60" aria-live="polite">
540
+ <com-spinner size="lg" color="primary" label="Loading..." />
541
+ </div>
542
+ }
543
+ </div>
544
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ComSpinner, selector: "com-spinner", inputs: ["label", "labelPosition", "size", "color"], exportAs: ["comSpinner"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
545
+ }
546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComTable, decorators: [{
547
+ type: Component,
548
+ args: [{
549
+ selector: 'com-table',
550
+ exportAs: 'comTable',
551
+ template: `
552
+ <div [class]="containerClasses()">
553
+ <table [class]="tableClasses()" [attr.aria-label]="ariaLabel()" [attr.aria-busy]="loading() || null">
554
+ <thead [class]="theadClasses()">
555
+ <tr>
556
+ @for (colName of headerColumns(); track colName) {
557
+ @let colDef = columnDefMap().get(colName);
558
+ @if (colDef?.headerCellDef(); as headerDef) {
559
+ <th [class]="thClasses()" scope="col">
560
+ <ng-container [ngTemplateOutlet]="headerDef.templateRef" />
561
+ </th>
562
+ }
563
+ }
564
+ </tr>
565
+ </thead>
566
+
567
+ <tbody>
568
+ @if (!loading() && renderData().length === 0 && noDataRow()) {
569
+ <tr>
570
+ <ng-container [ngTemplateOutlet]="noDataRow()!.templateRef" />
571
+ </tr>
572
+ } @else {
573
+ @for (row of renderData(); track trackByFn()($index, row); let idx = $index) {
574
+ <tr [class]="trClasses()">
575
+ @for (colName of bodyColumns(); track colName) {
576
+ @let colDef = columnDefMap().get(colName);
577
+ @if (colDef?.cellDef(); as cellDef) {
578
+ <td [class]="tdClasses()">
579
+ <ng-container
580
+ [ngTemplateOutlet]="cellDef.templateRef"
581
+ [ngTemplateOutletContext]="{ $implicit: row, index: idx }"
582
+ />
583
+ </td>
584
+ }
585
+ }
586
+ </tr>
587
+ }
588
+ }
589
+ </tbody>
590
+
591
+ @if (footerRowDef()) {
592
+ <tfoot>
593
+ <tr>
594
+ @for (colName of footerColumns(); track colName) {
595
+ @let colDef = columnDefMap().get(colName);
596
+ @if (colDef?.footerCellDef(); as footerDef) {
597
+ <td [class]="tfootTdClasses()">
598
+ <ng-container [ngTemplateOutlet]="footerDef.templateRef" />
599
+ </td>
600
+ }
601
+ }
602
+ </tr>
603
+ </tfoot>
604
+ }
605
+ </table>
606
+
607
+ @if (loading()) {
608
+ <div class="absolute inset-0 flex items-center justify-center bg-background/60" aria-live="polite">
609
+ <com-spinner size="lg" color="primary" label="Loading..." />
610
+ </div>
611
+ }
612
+ </div>
613
+ `,
614
+ imports: [NgTemplateOutlet, ComSpinner],
615
+ changeDetection: ChangeDetectionStrategy.OnPush,
616
+ encapsulation: ViewEncapsulation.None,
617
+ host: {
618
+ class: 'block',
619
+ },
620
+ }]
621
+ }], ctorParameters: () => [], propDecorators: { dataSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataSource", required: false }] }], trackByFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "trackByFn", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], density: [{ type: i0.Input, args: [{ isSignal: true, alias: "density", required: false }] }], stickyHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "stickyHeader", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], columnDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => ComColumnDef), { isSignal: true }] }], headerRowDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComHeaderRowDef), { isSignal: true }] }], rowDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComRowDef), { isSignal: true }] }], footerRowDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComFooterRowDef), { isSignal: true }] }], noDataRow: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ComNoDataRow), { isSignal: true }] }] } });
622
+
623
+ // Public API for the table component system
624
+ // Main component
625
+
626
+ /**
627
+ * Generated bundle index. Do not edit.
628
+ */
629
+
630
+ export { ComArrayDataSource, ComCellDef, ComColumnDef, ComDataSource, ComFooterCellDef, ComFooterRowDef, ComHeaderCellDef, ComHeaderRowDef, ComNoDataRow, ComRowDef, ComTable, isDataSource, tableBodyCellVariants, tableContainerVariants, tableFooterCellVariants, tableHeaderCellVariants, tableHeaderVariants, tableRowVariants, tableVariants };
631
+ //# sourceMappingURL=ngx-com-components-table.mjs.map