@tanstack/angular-table 9.0.0-alpha.4 → 9.0.0-alpha.41

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 (42) hide show
  1. package/README.md +117 -0
  2. package/dist/README.md +117 -0
  3. package/dist/fesm2022/tanstack-angular-table-static-functions.mjs +6 -0
  4. package/dist/fesm2022/tanstack-angular-table-static-functions.mjs.map +1 -0
  5. package/dist/fesm2022/tanstack-angular-table.mjs +1225 -258
  6. package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
  7. package/dist/types/tanstack-angular-table-static-functions.d.ts +1 -0
  8. package/dist/types/tanstack-angular-table.d.ts +795 -0
  9. package/package.json +37 -18
  10. package/src/flex-render/context.ts +14 -0
  11. package/src/flex-render/flags.ts +34 -0
  12. package/src/flex-render/flexRenderComponent.ts +288 -0
  13. package/src/flex-render/flexRenderComponentFactory.ts +241 -0
  14. package/src/flex-render/renderer.ts +393 -0
  15. package/src/flex-render/view.ts +207 -0
  16. package/src/flexRender.ts +124 -0
  17. package/src/helpers/cell.ts +104 -0
  18. package/src/helpers/createTableHook.ts +480 -0
  19. package/src/helpers/flexRenderCell.ts +136 -0
  20. package/src/helpers/header.ts +99 -0
  21. package/src/helpers/table.ts +87 -0
  22. package/src/index.ts +21 -70
  23. package/src/injectTable.ts +238 -0
  24. package/src/{lazy-signal-initializer.ts → lazySignalInitializer.ts} +2 -2
  25. package/static-functions/index.ts +1 -0
  26. package/static-functions/ng-package.json +6 -0
  27. package/dist/esm2022/flex-render.mjs +0 -150
  28. package/dist/esm2022/index.mjs +0 -48
  29. package/dist/esm2022/lazy-signal-initializer.mjs +0 -43
  30. package/dist/esm2022/proxy.mjs +0 -83
  31. package/dist/esm2022/tanstack-angular-table.mjs +0 -5
  32. package/dist/flex-render.d.ts +0 -31
  33. package/dist/index.d.ts +0 -5
  34. package/dist/lazy-signal-initializer.d.ts +0 -5
  35. package/dist/proxy.d.ts +0 -3
  36. package/src/__tests__/createAngularTable.test.ts +0 -95
  37. package/src/__tests__/flex-render.test.ts +0 -178
  38. package/src/__tests__/lazy-init.test.ts +0 -124
  39. package/src/__tests__/test-setup.ts +0 -12
  40. package/src/__tests__/test-utils.ts +0 -62
  41. package/src/flex-render.ts +0 -187
  42. package/src/proxy.ts +0 -97
@@ -0,0 +1,124 @@
1
+ import {
2
+ DestroyRef,
3
+ Directive,
4
+ Injector,
5
+ InputSignal,
6
+ TemplateRef,
7
+ ViewContainerRef,
8
+ inject,
9
+ input,
10
+ } from '@angular/core'
11
+ import {
12
+ FlexRenderInputContent,
13
+ FlexViewRenderer,
14
+ } from './flex-render/renderer'
15
+ import type {
16
+ CellContext,
17
+ CellData,
18
+ HeaderContext,
19
+ RowData,
20
+ TableFeatures,
21
+ } from '@tanstack/table-core'
22
+
23
+ export {
24
+ injectFlexRenderContext,
25
+ type FlexRenderComponentProps,
26
+ } from './flex-render/context'
27
+
28
+ export type {
29
+ FlexRenderInputContent,
30
+ FlexRenderContent,
31
+ } from './flex-render/renderer'
32
+
33
+ /**
34
+ * Use this utility directive to render headers, cells, or footers with custom markup.
35
+ *
36
+ * Note: If you are rendering cell, header, or footer without custom context or other props,
37
+ * you can use the {@link FlexRenderCell} directive as shorthand instead .
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import {FlexRender} from '@tanstack/angular-table';
42
+ *
43
+ * @Component({
44
+ * imports: [FlexRender],
45
+ * template: `
46
+ * <td
47
+ * *flexRender="
48
+ * cell.column.columnDef.cell;
49
+ * props: cell.getContext();
50
+ * let cell"
51
+ * >
52
+ * {{cell}}
53
+ * </td>
54
+ *
55
+ * <th
56
+ * *flexRender="
57
+ * header.column.columnDef.header;
58
+ * props: header.getContext();
59
+ * let header"
60
+ * >
61
+ * {{header}}
62
+ * </td>
63
+ *
64
+ * <td
65
+ * *flexRender="
66
+ * footer.column.columnDef.footer;
67
+ * props: footer.getContext();
68
+ * let footer"
69
+ * >
70
+ * {{footer}}
71
+ * </td>
72
+ * `,
73
+ * })
74
+ * class App {
75
+ * }
76
+ * ```
77
+ *
78
+ * Can be imported through {@link FlexRenderDirective} or {@link FlexRender} import,
79
+ * which the latter is preferred.
80
+ */
81
+ @Directive({
82
+ selector: 'ng-template[flexRender]',
83
+ })
84
+ export class FlexRenderDirective<
85
+ TFeatures extends TableFeatures,
86
+ TRowData extends RowData,
87
+ TValue extends CellData,
88
+ TProps extends
89
+ | NonNullable<unknown>
90
+ | CellContext<TFeatures, TRowData, TValue>
91
+ | HeaderContext<TFeatures, TRowData, TValue>,
92
+ > {
93
+ readonly content: InputSignal<FlexRenderInputContent<TProps>> = input(
94
+ undefined as FlexRenderInputContent<TProps>,
95
+ { alias: 'flexRender' },
96
+ )
97
+
98
+ readonly props = input<TProps>({} as TProps, {
99
+ alias: 'flexRenderProps',
100
+ })
101
+
102
+ readonly injector = input(inject(Injector), {
103
+ alias: 'flexRenderInjector',
104
+ })
105
+
106
+ readonly #viewContainerRef = inject(ViewContainerRef)
107
+ readonly #templateRef = inject(TemplateRef)
108
+
109
+ constructor() {
110
+ const renderer = new FlexViewRenderer({
111
+ content: this.content,
112
+ props: this.props,
113
+ injector: this.injector,
114
+ templateRef: this.#templateRef,
115
+ viewContainerRef: this.#viewContainerRef,
116
+ })
117
+
118
+ renderer.mount()
119
+
120
+ inject(DestroyRef).onDestroy(() => {
121
+ renderer.destroy()
122
+ })
123
+ }
124
+ }
@@ -0,0 +1,104 @@
1
+ import { Directive, InjectionToken, inject, input } from '@angular/core'
2
+ import { Cell, CellData, RowData, TableFeatures } from '@tanstack/table-core'
3
+ import type { Signal } from '@angular/core'
4
+
5
+ /**
6
+ * DI context shape for a TanStack Table cell.
7
+ *
8
+ * This exists to make the current `Cell` injectable by any nested component/directive
9
+ * without having to pass it through inputs/props manually.
10
+ */
11
+ export interface TanStackTableCellContext<
12
+ TFeatures extends TableFeatures,
13
+ TData extends RowData,
14
+ TValue extends CellData,
15
+ > {
16
+ /** Signal that returns the current cell instance. */
17
+ cell: Signal<Cell<TFeatures, TData, TValue>>
18
+ }
19
+
20
+ /**
21
+ * Injection token that provides access to the current cell.
22
+ *
23
+ * This token is provided by the {@link TanStackTableCell} directive.
24
+ */
25
+ export const TanStackTableCellToken = new InjectionToken<
26
+ TanStackTableCellContext<any, any, any>['cell']
27
+ >('[TanStack Table] CellContext')
28
+
29
+ /**
30
+ * Provides a TanStack Table `Cell` instance in Angular DI.
31
+ *
32
+ * The cell can be injected by:
33
+ * - any descendant of an element using `[tanStackTableCell]="..."`
34
+ * - any component instantiated by `*flexRender` when the render props contains `cell`
35
+ *
36
+ * @example
37
+ * Inject from the nearest `[tanStackTableCell]`:
38
+ * ```html
39
+ * <td [tanStackTableCell]="cell">
40
+ * <app-cell-actions />
41
+ * </td>
42
+ * ```
43
+ *
44
+ * ```ts
45
+ * @Component({
46
+ * selector: 'app-cell-actions',
47
+ * template: `{{ cell().id }}`,
48
+ * })
49
+ * export class CellActionsComponent {
50
+ * readonly cell = injectTableCellContext()
51
+ * }
52
+ * ```
53
+ *
54
+ * @example
55
+ * Inject inside a component rendered via `flexRender`:
56
+ * ```ts
57
+ * @Component({
58
+ * selector: 'app-price-cell',
59
+ * template: `{{ cell().getValue() }}`,
60
+ * })
61
+ * export class PriceCellComponent {
62
+ * readonly cell = injectTableCellContext()
63
+ * }
64
+ * ```
65
+ */
66
+ @Directive({
67
+ selector: '[tanStackTableCell]',
68
+ exportAs: 'cell',
69
+ providers: [
70
+ {
71
+ provide: TanStackTableCellToken,
72
+ useFactory: () => inject(TanStackTableCell).cell,
73
+ },
74
+ ],
75
+ })
76
+ export class TanStackTableCell<
77
+ TFeatures extends TableFeatures,
78
+ TData extends RowData,
79
+ TValue extends CellData,
80
+ > implements TanStackTableCellContext<TFeatures, TData, TValue> {
81
+ /**
82
+ * The current TanStack Table cell.
83
+ *
84
+ * Provided as a required signal input so DI consumers always read the latest value.
85
+ */
86
+ readonly cell = input.required<Cell<TFeatures, TData, TValue>>({
87
+ alias: 'tanStackTableCell',
88
+ })
89
+ }
90
+
91
+ /**
92
+ * Injects the current TanStack Table cell signal.
93
+ *
94
+ * Available when:
95
+ * - there is a nearest `[tanStackTableCell]` directive in the DI tree, or
96
+ * - the caller is rendered via `*flexRender` with render props containing `cell`
97
+ */
98
+ export function injectTableCellContext<
99
+ TFeatures extends TableFeatures,
100
+ TData extends RowData,
101
+ TValue extends CellData,
102
+ >(): TanStackTableCellContext<TFeatures, TData, TValue>['cell'] {
103
+ return inject(TanStackTableCellToken)
104
+ }
@@ -0,0 +1,480 @@
1
+ import { createColumnHelper as coreCreateColumnHelper } from '@tanstack/table-core'
2
+ import { injectTable } from '../injectTable'
3
+ import { injectFlexRenderContext } from '../flexRender'
4
+ import { injectTableHeaderContext as _injectTableHeaderContext } from './header'
5
+ import { injectTableContext as _injectTableContext } from './table'
6
+ import { injectTableCellContext as _injectTableCellContext } from './cell'
7
+ import type { FlexRenderContent } from '../flexRender'
8
+ import type { AngularTable } from '../injectTable'
9
+ import type {
10
+ AccessorFn,
11
+ AccessorFnColumnDef,
12
+ AccessorKeyColumnDef,
13
+ Cell,
14
+ CellContext,
15
+ CellData,
16
+ Column,
17
+ ColumnDef,
18
+ DeepKeys,
19
+ DeepValue,
20
+ DisplayColumnDef,
21
+ GroupColumnDef,
22
+ Header,
23
+ HeaderContext,
24
+ IdentifiedColumnDef,
25
+ Row,
26
+ RowData,
27
+ Table,
28
+ TableFeature,
29
+ TableFeatures,
30
+ TableOptions,
31
+ TableState,
32
+ } from '@tanstack/table-core'
33
+ import type { Signal, Type } from '@angular/core'
34
+
35
+ export type RenderableComponent =
36
+ | Type<any>
37
+ | (<T extends NonNullable<unknown>>(props: T) => FlexRenderContent<T>)
38
+
39
+ // =============================================================================
40
+ // Enhanced Context Types with Pre-bound Components
41
+ // =============================================================================
42
+
43
+ /**
44
+ * Enhanced CellContext with pre-bound cell components.
45
+ * The `cell` property includes the registered cellComponents.
46
+ */
47
+ export type AppCellContext<
48
+ TFeatures extends TableFeatures,
49
+ TData extends RowData,
50
+ TValue extends CellData,
51
+ TCellComponents extends Record<string, RenderableComponent>,
52
+ > = {
53
+ cell: Cell<TFeatures, TData, TValue> &
54
+ TCellComponents & { FlexRender: () => unknown }
55
+ column: Column<TFeatures, TData, TValue>
56
+ getValue: CellContext<TFeatures, TData, TValue>['getValue']
57
+ renderValue: CellContext<TFeatures, TData, TValue>['renderValue']
58
+ row: Row<TFeatures, TData>
59
+ table: Table<TFeatures, TData>
60
+ }
61
+
62
+ /**
63
+ * Enhanced HeaderContext with pre-bound header components.
64
+ * The `header` property includes the registered headerComponents.
65
+ */
66
+ export type AppHeaderContext<
67
+ TFeatures extends TableFeatures,
68
+ TData extends RowData,
69
+ TValue extends CellData,
70
+ THeaderComponents extends Record<string, RenderableComponent>,
71
+ > = {
72
+ column: Column<TFeatures, TData, TValue>
73
+ header: Header<TFeatures, TData, TValue> &
74
+ THeaderComponents & { FlexRender: () => unknown }
75
+ table: Table<TFeatures, TData>
76
+ }
77
+
78
+ // =============================================================================
79
+ // Enhanced Column Definition Types
80
+ // =============================================================================
81
+
82
+ /**
83
+ * Template type for column definitions that can be a string or a function.
84
+ */
85
+ export type AppColumnDefTemplate<TProps extends object> =
86
+ | string
87
+ | ((props: TProps) => any)
88
+
89
+ /**
90
+ * Enhanced column definition base with pre-bound components in cell/header/footer contexts.
91
+ */
92
+ export type AppColumnDefBase<
93
+ TFeatures extends TableFeatures,
94
+ TData extends RowData,
95
+ TValue extends CellData,
96
+ TCellComponents extends Record<string, RenderableComponent>,
97
+ THeaderComponents extends Record<string, RenderableComponent>,
98
+ > = Omit<
99
+ IdentifiedColumnDef<TFeatures, TData, TValue>,
100
+ 'cell' | 'header' | 'footer'
101
+ > & {
102
+ cell?: AppColumnDefTemplate<
103
+ AppCellContext<TFeatures, TData, TValue, TCellComponents>
104
+ >
105
+ header?: AppColumnDefTemplate<
106
+ AppHeaderContext<TFeatures, TData, TValue, THeaderComponents>
107
+ >
108
+ footer?: AppColumnDefTemplate<
109
+ AppHeaderContext<TFeatures, TData, TValue, THeaderComponents>
110
+ >
111
+ }
112
+
113
+ /**
114
+ * Enhanced display column definition with pre-bound components.
115
+ */
116
+ export type AppDisplayColumnDef<
117
+ TFeatures extends TableFeatures,
118
+ TData extends RowData,
119
+ TCellComponents extends Record<string, RenderableComponent>,
120
+ THeaderComponents extends Record<string, RenderableComponent>,
121
+ > = Omit<
122
+ DisplayColumnDef<TFeatures, TData, unknown>,
123
+ 'cell' | 'header' | 'footer'
124
+ > & {
125
+ cell?: AppColumnDefTemplate<
126
+ AppCellContext<TFeatures, TData, unknown, TCellComponents>
127
+ >
128
+ header?: AppColumnDefTemplate<
129
+ AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>
130
+ >
131
+ footer?: AppColumnDefTemplate<
132
+ AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>
133
+ >
134
+ }
135
+
136
+ /**
137
+ * Enhanced group column definition with pre-bound components.
138
+ */
139
+ export type AppGroupColumnDef<
140
+ TFeatures extends TableFeatures,
141
+ TData extends RowData,
142
+ TCellComponents extends Record<string, RenderableComponent>,
143
+ THeaderComponents extends Record<string, RenderableComponent>,
144
+ > = Omit<
145
+ GroupColumnDef<TFeatures, TData, unknown>,
146
+ 'cell' | 'header' | 'footer' | 'columns'
147
+ > & {
148
+ cell?: AppColumnDefTemplate<
149
+ AppCellContext<TFeatures, TData, unknown, TCellComponents>
150
+ >
151
+ header?: AppColumnDefTemplate<
152
+ AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>
153
+ >
154
+ footer?: AppColumnDefTemplate<
155
+ AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>
156
+ >
157
+ columns?: ReadonlyArray<ColumnDef<TFeatures, TData, unknown>>
158
+ }
159
+
160
+ // =============================================================================
161
+ // Enhanced Column Helper Type
162
+ // =============================================================================
163
+
164
+ /**
165
+ * Enhanced column helper with pre-bound components in cell/header/footer contexts.
166
+ * This enables TypeScript to know about the registered components when defining columns.
167
+ */
168
+ export type AppColumnHelper<
169
+ TFeatures extends TableFeatures,
170
+ TData extends RowData,
171
+ TCellComponents extends Record<string, RenderableComponent>,
172
+ THeaderComponents extends Record<string, RenderableComponent>,
173
+ > = {
174
+ /**
175
+ * Creates a data column definition with an accessor key or function.
176
+ * The cell, header, and footer contexts include pre-bound components.
177
+ */
178
+ accessor: <
179
+ TAccessor extends AccessorFn<TData> | DeepKeys<TData>,
180
+ TValue extends TAccessor extends AccessorFn<TData, infer TReturn>
181
+ ? TReturn
182
+ : TAccessor extends DeepKeys<TData>
183
+ ? DeepValue<TData, TAccessor>
184
+ : never,
185
+ >(
186
+ accessor: TAccessor,
187
+ column: TAccessor extends AccessorFn<TData>
188
+ ? AppColumnDefBase<
189
+ TFeatures,
190
+ TData,
191
+ TValue,
192
+ TCellComponents,
193
+ THeaderComponents
194
+ > & { id: string }
195
+ : AppColumnDefBase<
196
+ TFeatures,
197
+ TData,
198
+ TValue,
199
+ TCellComponents,
200
+ THeaderComponents
201
+ >,
202
+ ) => TAccessor extends AccessorFn<TData>
203
+ ? AccessorFnColumnDef<TFeatures, TData, TValue>
204
+ : AccessorKeyColumnDef<TFeatures, TData, TValue>
205
+
206
+ /**
207
+ * Wraps an array of column definitions to preserve each column's individual TValue type.
208
+ */
209
+ columns: <TColumns extends ReadonlyArray<ColumnDef<TFeatures, TData, any>>>(
210
+ columns: [...TColumns],
211
+ ) => Array<ColumnDef<TFeatures, TData, any>> & [...TColumns]
212
+
213
+ /**
214
+ * Creates a display column definition for non-data columns.
215
+ * The cell, header, and footer contexts include pre-bound components.
216
+ */
217
+ display: (
218
+ column: AppDisplayColumnDef<
219
+ TFeatures,
220
+ TData,
221
+ TCellComponents,
222
+ THeaderComponents
223
+ >,
224
+ ) => DisplayColumnDef<TFeatures, TData, unknown>
225
+
226
+ /**
227
+ * Creates a group column definition with nested child columns.
228
+ * The cell, header, and footer contexts include pre-bound components.
229
+ */
230
+ group: (
231
+ column: AppGroupColumnDef<
232
+ TFeatures,
233
+ TData,
234
+ TCellComponents,
235
+ THeaderComponents
236
+ >,
237
+ ) => GroupColumnDef<TFeatures, TData, unknown>
238
+ }
239
+
240
+ /**
241
+ * Extended table API returned by useAppTable with all App wrapper components
242
+ */
243
+ export type AppAngularTable<
244
+ TFeatures extends TableFeatures,
245
+ TData extends RowData,
246
+ TSelected,
247
+ TTableComponents extends Record<string, RenderableComponent>,
248
+ TCellComponents extends Record<string, RenderableComponent>,
249
+ THeaderComponents extends Record<string, RenderableComponent>,
250
+ > = AngularTable<TFeatures, TData, TSelected> &
251
+ NoInfer<TTableComponents> & {
252
+ appCell: <TValue>(
253
+ cell: Cell<TFeatures, TData, TValue>,
254
+ ) => Cell<TFeatures, TData, TValue> & NoInfer<TCellComponents>
255
+
256
+ appHeader: <TValue>(
257
+ header: Header<TFeatures, TData, TValue>,
258
+ ) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>
259
+
260
+ appFooter: <TValue>(
261
+ footer: Header<TFeatures, TData, TValue>,
262
+ ) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>
263
+ }
264
+
265
+ // =============================================================================
266
+ // CreateTableHook Options and Props
267
+ // =============================================================================
268
+
269
+ /**
270
+ * Options for creating a table hook with pre-bound components and default table options.
271
+ * Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'.
272
+ */
273
+ export type CreateTableContextOptions<
274
+ TFeatures extends TableFeatures,
275
+ TTableComponents extends Record<string, RenderableComponent>,
276
+ TCellComponents extends Record<string, RenderableComponent>,
277
+ THeaderComponents extends Record<string, RenderableComponent>,
278
+ > = Omit<
279
+ TableOptions<TFeatures, any>,
280
+ 'columns' | 'data' | 'store' | 'state' | 'initialState'
281
+ > & {
282
+ /**
283
+ * Table-level components that need access to the table instance.
284
+ * These are available directly on the table object returned by useAppTable.
285
+ * Use `useTableContext()` inside these components.
286
+ * @example { PaginationControls, GlobalFilter, RowCount }
287
+ */
288
+ tableComponents?: TTableComponents
289
+ /**
290
+ * Cell-level components that need access to the cell instance.
291
+ * These are available on the cell object passed to AppCell's children.
292
+ * Use `useCellContext()` inside these components.
293
+ * @example { TextCell, NumberCell, DateCell, CurrencyCell }
294
+ */
295
+ cellComponents?: TCellComponents
296
+ /**
297
+ * Header-level components that need access to the header instance.
298
+ * These are available on the header object passed to AppHeader/AppFooter's children.
299
+ * Use `useHeaderContext()` inside these components.
300
+ * @example { SortIndicator, ColumnFilter, ResizeHandle }
301
+ */
302
+ headerComponents?: THeaderComponents
303
+ }
304
+
305
+ export type CreateTableHookResult<
306
+ TFeatures extends TableFeatures,
307
+ TTableComponents extends Record<string, RenderableComponent>,
308
+ TCellComponents extends Record<string, RenderableComponent>,
309
+ THeaderComponents extends Record<string, RenderableComponent>,
310
+ > = {
311
+ createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<
312
+ TFeatures,
313
+ TData,
314
+ TCellComponents,
315
+ THeaderComponents
316
+ >
317
+ injectTableContext: <TData extends RowData = RowData>() => Signal<
318
+ AngularTable<TFeatures, TData>
319
+ >
320
+ injectTableHeaderContext: <
321
+ TValue extends CellData = CellData,
322
+ TRowData extends RowData = RowData,
323
+ >() => Signal<Header<TFeatures, TRowData, TValue>>
324
+ injectTableCellContext: <
325
+ TValue extends CellData = CellData,
326
+ TRowData extends RowData = RowData,
327
+ >() => Signal<Cell<TFeatures, TRowData, TValue>>
328
+ injectFlexRenderHeaderContext: <
329
+ TData extends RowData,
330
+ TValue extends CellData,
331
+ >() => HeaderContext<TFeatures, TData, TValue>
332
+ injectFlexRenderCellContext: <
333
+ TData extends RowData,
334
+ TValue extends CellData,
335
+ >() => CellContext<TFeatures, TData, TValue>
336
+ injectAppTable: <TData extends RowData, TSelected = TableState<TFeatures>>(
337
+ tableOptions: () => Omit<
338
+ TableOptions<TFeatures, TData>,
339
+ '_features' | '_rowModels'
340
+ >,
341
+ selector?: (state: TableState<TFeatures>) => TSelected,
342
+ ) => AppAngularTable<
343
+ TFeatures,
344
+ TData,
345
+ TSelected,
346
+ TTableComponents,
347
+ TCellComponents,
348
+ THeaderComponents
349
+ >
350
+ }
351
+
352
+ export function createTableHook<
353
+ TFeatures extends TableFeatures,
354
+ const TTableComponents extends Record<string, RenderableComponent>,
355
+ const TCellComponents extends Record<string, RenderableComponent>,
356
+ const THeaderComponents extends Record<string, RenderableComponent>,
357
+ >({
358
+ tableComponents,
359
+ cellComponents,
360
+ headerComponents,
361
+ ...defaultTableOptions
362
+ }: CreateTableContextOptions<
363
+ TFeatures,
364
+ TTableComponents,
365
+ TCellComponents,
366
+ THeaderComponents
367
+ >): CreateTableHookResult<
368
+ TFeatures,
369
+ TTableComponents,
370
+ TCellComponents,
371
+ THeaderComponents
372
+ > {
373
+ function injectTableContext<TData extends RowData = RowData>(): Signal<
374
+ AngularTable<TFeatures, TData>
375
+ > {
376
+ return _injectTableContext<TFeatures, TData>()
377
+ }
378
+
379
+ function injectTableHeaderContext<
380
+ TValue extends CellData = CellData,
381
+ TRowData extends RowData = RowData,
382
+ >(): Signal<Header<TFeatures, TRowData, TValue>> {
383
+ return _injectTableHeaderContext<TFeatures, TRowData, TValue>()
384
+ }
385
+
386
+ function injectTableCellContext<
387
+ TValue extends CellData = CellData,
388
+ TRowData extends RowData = RowData,
389
+ >(): Signal<Cell<TFeatures, TRowData, TValue>> {
390
+ return _injectTableCellContext<TFeatures, TRowData, TValue>()
391
+ }
392
+
393
+ function injectFlexRenderHeaderContext<
394
+ TData extends RowData,
395
+ TValue extends CellData,
396
+ >(): HeaderContext<TFeatures, TData, TValue> {
397
+ return injectFlexRenderContext<HeaderContext<TFeatures, TData, TValue>>()
398
+ }
399
+
400
+ function injectFlexRenderCellContext<
401
+ TData extends RowData,
402
+ TValue extends CellData,
403
+ >(): CellContext<TFeatures, TData, TValue> {
404
+ return injectFlexRenderContext<CellContext<TFeatures, TData, TValue>>()
405
+ }
406
+
407
+ function injectAppTable<TData extends RowData, TSelected = {}>(
408
+ tableOptions: () => Omit<
409
+ TableOptions<TFeatures, TData>,
410
+ '_features' | '_rowModels'
411
+ >,
412
+ selector?: (state: TableState<TFeatures>) => TSelected,
413
+ ): AppAngularTable<
414
+ TFeatures,
415
+ TData,
416
+ TSelected,
417
+ TTableComponents,
418
+ TCellComponents,
419
+ THeaderComponents
420
+ > {
421
+ function appCell(cell: Cell<TFeatures, TData, any>) {
422
+ return cell as Cell<TFeatures, TData, any> & TCellComponents
423
+ }
424
+
425
+ function appHeader(header: Header<TFeatures, TData, any>) {
426
+ return header as Header<TFeatures, TData, any> & THeaderComponents
427
+ }
428
+
429
+ function appFooter(footer: Header<TFeatures, TData, any>) {
430
+ return footer as Header<TFeatures, TData, any> & THeaderComponents
431
+ }
432
+
433
+ const appTableFeatures: TableFeature<{}> = {
434
+ constructTableAPIs: (table) => {
435
+ Object.assign(table, tableComponents, { appCell, appHeader, appFooter })
436
+ },
437
+ assignCellPrototype(prototype) {
438
+ Object.assign(prototype, cellComponents)
439
+ },
440
+ assignHeaderPrototype(prototype) {
441
+ Object.assign(prototype, headerComponents)
442
+ },
443
+ }
444
+
445
+ return injectTable<TFeatures, TData, TSelected>(() => {
446
+ const options = {
447
+ ...defaultTableOptions,
448
+ ...tableOptions(),
449
+ } as TableOptions<TFeatures, TData>
450
+ options._features = { ...options._features, appTableFeatures }
451
+ return options
452
+ }, selector) as AngularTable<any, any>
453
+ }
454
+
455
+ function createAppColumnHelper<TData extends RowData>(): AppColumnHelper<
456
+ TFeatures,
457
+ TData,
458
+ TCellComponents,
459
+ THeaderComponents
460
+ > {
461
+ // The runtime implementation is the same - components are attached at render time
462
+ // This cast provides the enhanced types for column definitions
463
+ return coreCreateColumnHelper<TFeatures, TData>() as AppColumnHelper<
464
+ TFeatures,
465
+ TData,
466
+ TCellComponents,
467
+ THeaderComponents
468
+ >
469
+ }
470
+
471
+ return {
472
+ createAppColumnHelper,
473
+ injectTableContext,
474
+ injectTableHeaderContext,
475
+ injectTableCellContext,
476
+ injectFlexRenderHeaderContext,
477
+ injectFlexRenderCellContext,
478
+ injectAppTable,
479
+ }
480
+ }