@tanstack/angular-table 9.0.0-alpha.9 → 9.0.0-beta.2
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.
- package/README.md +127 -0
- package/dist/README.md +127 -0
- package/dist/fesm2022/tanstack-angular-table-static-functions.mjs +6 -0
- package/dist/fesm2022/tanstack-angular-table-static-functions.mjs.map +1 -0
- package/dist/fesm2022/tanstack-angular-table.mjs +1337 -239
- package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
- package/dist/types/tanstack-angular-table-static-functions.d.ts +1 -0
- package/dist/types/tanstack-angular-table.d.ts +793 -0
- package/package.json +39 -19
- package/skills/angular/angular-rendering-directives/SKILL.md +415 -0
- package/skills/angular/angular-rendering-directives/references/content-shapes.md +142 -0
- package/skills/angular/angular-rendering-directives/references/create-table-hook-registries.md +89 -0
- package/skills/angular/angular-rendering-directives/references/di-tokens.md +171 -0
- package/skills/angular/angular-rendering-directives/references/flex-render-component-options.md +64 -0
- package/skills/angular/client-to-server/SKILL.md +467 -0
- package/skills/angular/compose-with-tanstack-query/SKILL.md +482 -0
- package/skills/angular/compose-with-tanstack-store/SKILL.md +397 -0
- package/skills/angular/compose-with-tanstack-virtual/SKILL.md +400 -0
- package/skills/angular/getting-started/SKILL.md +496 -0
- package/skills/angular/getting-started/references/feature-row-model-mapping.md +48 -0
- package/skills/angular/migrate-v8-to-v9/SKILL.md +419 -0
- package/skills/angular/migrate-v8-to-v9/references/v8-to-v9-mapping.md +261 -0
- package/skills/angular/production-readiness/SKILL.md +469 -0
- package/skills/angular/table-state/SKILL.md +429 -0
- package/skills/angular/table-state/references/external-atoms-and-app-hook.md +152 -0
- package/src/flex-render/context.ts +14 -0
- package/src/flex-render/flags.ts +34 -0
- package/src/flex-render/flexRenderComponent.ts +288 -0
- package/src/flex-render/flexRenderComponentFactory.ts +251 -0
- package/src/flex-render/renderer.ts +393 -0
- package/src/flex-render/view.ts +226 -0
- package/src/flexRender.ts +124 -0
- package/src/helpers/cell.ts +104 -0
- package/src/helpers/createTableHook.ts +499 -0
- package/src/helpers/flexRenderCell.ts +136 -0
- package/src/helpers/header.ts +99 -0
- package/src/helpers/table.ts +85 -0
- package/src/index.ts +23 -70
- package/src/injectTable.ts +212 -0
- package/src/{lazy-signal-initializer.ts → lazySignalInitializer.ts} +2 -2
- package/src/reactivity.ts +105 -0
- package/static-functions/index.ts +1 -0
- package/static-functions/ng-package.json +6 -0
- package/dist/esm2022/flex-render.mjs +0 -148
- package/dist/esm2022/index.mjs +0 -48
- package/dist/esm2022/lazy-signal-initializer.mjs +0 -43
- package/dist/esm2022/proxy.mjs +0 -83
- package/dist/esm2022/tanstack-angular-table.mjs +0 -5
- package/dist/flex-render.d.ts +0 -30
- package/dist/index.d.ts +0 -5
- package/dist/lazy-signal-initializer.d.ts +0 -5
- package/dist/proxy.d.ts +0 -3
- package/src/flex-render.ts +0 -184
- package/src/proxy.ts +0 -97
|
@@ -0,0 +1,499 @@
|
|
|
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
|
+
TTableComponents extends Record<string, RenderableComponent>,
|
|
247
|
+
TCellComponents extends Record<string, RenderableComponent>,
|
|
248
|
+
THeaderComponents extends Record<string, RenderableComponent>,
|
|
249
|
+
> = AngularTable<TFeatures, TData> &
|
|
250
|
+
NoInfer<TTableComponents> & {
|
|
251
|
+
appCell: <TValue>(
|
|
252
|
+
cell: Cell<TFeatures, TData, TValue>,
|
|
253
|
+
) => Cell<TFeatures, TData, TValue> & NoInfer<TCellComponents>
|
|
254
|
+
|
|
255
|
+
appHeader: <TValue>(
|
|
256
|
+
header: Header<TFeatures, TData, TValue>,
|
|
257
|
+
) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>
|
|
258
|
+
|
|
259
|
+
appFooter: <TValue>(
|
|
260
|
+
footer: Header<TFeatures, TData, TValue>,
|
|
261
|
+
) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// =============================================================================
|
|
265
|
+
// CreateTableHook Options and Props
|
|
266
|
+
// =============================================================================
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Options for creating a table hook with pre-bound components and default table options.
|
|
270
|
+
* Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'.
|
|
271
|
+
*/
|
|
272
|
+
export type CreateTableContextOptions<
|
|
273
|
+
TFeatures extends TableFeatures,
|
|
274
|
+
TTableComponents extends Record<string, RenderableComponent>,
|
|
275
|
+
TCellComponents extends Record<string, RenderableComponent>,
|
|
276
|
+
THeaderComponents extends Record<string, RenderableComponent>,
|
|
277
|
+
> = Omit<
|
|
278
|
+
TableOptions<TFeatures, any>,
|
|
279
|
+
'columns' | 'data' | 'store' | 'state' | 'initialState'
|
|
280
|
+
> & {
|
|
281
|
+
/**
|
|
282
|
+
* Table-level components that need access to the table instance.
|
|
283
|
+
* These are available directly on the table object returned by useAppTable.
|
|
284
|
+
* Use `useTableContext()` inside these components.
|
|
285
|
+
* @example { PaginationControls, GlobalFilter, RowCount }
|
|
286
|
+
*/
|
|
287
|
+
tableComponents?: TTableComponents
|
|
288
|
+
/**
|
|
289
|
+
* Cell-level components that need access to the cell instance.
|
|
290
|
+
* These are available on the cell object passed to AppCell's children.
|
|
291
|
+
* Use `useCellContext()` inside these components.
|
|
292
|
+
* @example { TextCell, NumberCell, DateCell, CurrencyCell }
|
|
293
|
+
*/
|
|
294
|
+
cellComponents?: TCellComponents
|
|
295
|
+
/**
|
|
296
|
+
* Header-level components that need access to the header instance.
|
|
297
|
+
* These are available on the header object passed to AppHeader/AppFooter's children.
|
|
298
|
+
* Use `useHeaderContext()` inside these components.
|
|
299
|
+
* @example { SortIndicator, ColumnFilter, ResizeHandle }
|
|
300
|
+
*/
|
|
301
|
+
headerComponents?: THeaderComponents
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export type CreateTableHookResult<
|
|
305
|
+
TFeatures extends TableFeatures,
|
|
306
|
+
TTableComponents extends Record<string, RenderableComponent>,
|
|
307
|
+
TCellComponents extends Record<string, RenderableComponent>,
|
|
308
|
+
THeaderComponents extends Record<string, RenderableComponent>,
|
|
309
|
+
> = {
|
|
310
|
+
createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<
|
|
311
|
+
TFeatures,
|
|
312
|
+
TData,
|
|
313
|
+
TCellComponents,
|
|
314
|
+
THeaderComponents
|
|
315
|
+
>
|
|
316
|
+
injectTableContext: <TData extends RowData = RowData>() => Signal<
|
|
317
|
+
AngularTable<TFeatures, TData>
|
|
318
|
+
>
|
|
319
|
+
injectTableHeaderContext: <
|
|
320
|
+
TValue extends CellData = CellData,
|
|
321
|
+
TRowData extends RowData = RowData,
|
|
322
|
+
>() => Signal<Header<TFeatures, TRowData, TValue>>
|
|
323
|
+
injectTableCellContext: <
|
|
324
|
+
TValue extends CellData = CellData,
|
|
325
|
+
TRowData extends RowData = RowData,
|
|
326
|
+
>() => Signal<Cell<TFeatures, TRowData, TValue>>
|
|
327
|
+
injectFlexRenderHeaderContext: <
|
|
328
|
+
TData extends RowData,
|
|
329
|
+
TValue extends CellData,
|
|
330
|
+
>() => HeaderContext<TFeatures, TData, TValue>
|
|
331
|
+
injectFlexRenderCellContext: <
|
|
332
|
+
TData extends RowData,
|
|
333
|
+
TValue extends CellData,
|
|
334
|
+
>() => CellContext<TFeatures, TData, TValue>
|
|
335
|
+
injectAppTable: <TData extends RowData>(
|
|
336
|
+
tableOptions: () => Omit<
|
|
337
|
+
TableOptions<TFeatures, TData>,
|
|
338
|
+
'features' | 'rowModels'
|
|
339
|
+
>,
|
|
340
|
+
) => AppAngularTable<
|
|
341
|
+
TFeatures,
|
|
342
|
+
TData,
|
|
343
|
+
TTableComponents,
|
|
344
|
+
TCellComponents,
|
|
345
|
+
THeaderComponents
|
|
346
|
+
>
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Creates app-scoped Angular table helpers with features, row models, and
|
|
351
|
+
* renderable component maps pre-bound.
|
|
352
|
+
*
|
|
353
|
+
* Use this when an app or design system wants typed `injectAppTable`,
|
|
354
|
+
* pre-bound column helpers, and typed table/cell/header context injection
|
|
355
|
+
* helpers without repeating the same feature and component generics.
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* ```ts
|
|
359
|
+
* const { injectAppTable, createAppColumnHelper } = createTableHook({
|
|
360
|
+
* features,
|
|
361
|
+
* rowModels: {},
|
|
362
|
+
* tableComponents: {},
|
|
363
|
+
* cellComponents: {},
|
|
364
|
+
* headerComponents: {},
|
|
365
|
+
* })
|
|
366
|
+
* ```
|
|
367
|
+
*/
|
|
368
|
+
export function createTableHook<
|
|
369
|
+
TFeatures extends TableFeatures,
|
|
370
|
+
const TTableComponents extends Record<string, RenderableComponent>,
|
|
371
|
+
const TCellComponents extends Record<string, RenderableComponent>,
|
|
372
|
+
const THeaderComponents extends Record<string, RenderableComponent>,
|
|
373
|
+
>({
|
|
374
|
+
tableComponents,
|
|
375
|
+
cellComponents,
|
|
376
|
+
headerComponents,
|
|
377
|
+
...defaultTableOptions
|
|
378
|
+
}: CreateTableContextOptions<
|
|
379
|
+
TFeatures,
|
|
380
|
+
TTableComponents,
|
|
381
|
+
TCellComponents,
|
|
382
|
+
THeaderComponents
|
|
383
|
+
>): CreateTableHookResult<
|
|
384
|
+
TFeatures,
|
|
385
|
+
TTableComponents,
|
|
386
|
+
TCellComponents,
|
|
387
|
+
THeaderComponents
|
|
388
|
+
> {
|
|
389
|
+
function injectTableContext<TData extends RowData = RowData>(): Signal<
|
|
390
|
+
AngularTable<TFeatures, TData>
|
|
391
|
+
> {
|
|
392
|
+
return _injectTableContext<TFeatures, TData>()
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function injectTableHeaderContext<
|
|
396
|
+
TValue extends CellData = CellData,
|
|
397
|
+
TRowData extends RowData = RowData,
|
|
398
|
+
>(): Signal<Header<TFeatures, TRowData, TValue>> {
|
|
399
|
+
return _injectTableHeaderContext<TFeatures, TRowData, TValue>()
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function injectTableCellContext<
|
|
403
|
+
TValue extends CellData = CellData,
|
|
404
|
+
TRowData extends RowData = RowData,
|
|
405
|
+
>(): Signal<Cell<TFeatures, TRowData, TValue>> {
|
|
406
|
+
return _injectTableCellContext<TFeatures, TRowData, TValue>()
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function injectFlexRenderHeaderContext<
|
|
410
|
+
TData extends RowData,
|
|
411
|
+
TValue extends CellData,
|
|
412
|
+
>(): HeaderContext<TFeatures, TData, TValue> {
|
|
413
|
+
return injectFlexRenderContext<HeaderContext<TFeatures, TData, TValue>>()
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
function injectFlexRenderCellContext<
|
|
417
|
+
TData extends RowData,
|
|
418
|
+
TValue extends CellData,
|
|
419
|
+
>(): CellContext<TFeatures, TData, TValue> {
|
|
420
|
+
return injectFlexRenderContext<CellContext<TFeatures, TData, TValue>>()
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function injectAppTable<
|
|
424
|
+
TData extends RowData,
|
|
425
|
+
TSelected = TableState<TFeatures>,
|
|
426
|
+
>(
|
|
427
|
+
tableOptions: () => Omit<
|
|
428
|
+
TableOptions<TFeatures, TData>,
|
|
429
|
+
'features' | 'rowModels'
|
|
430
|
+
>,
|
|
431
|
+
): AppAngularTable<
|
|
432
|
+
TFeatures,
|
|
433
|
+
TData,
|
|
434
|
+
TTableComponents,
|
|
435
|
+
TCellComponents,
|
|
436
|
+
THeaderComponents
|
|
437
|
+
> {
|
|
438
|
+
function appCell(cell: Cell<TFeatures, TData, any>) {
|
|
439
|
+
return cell as Cell<TFeatures, TData, any> & TCellComponents
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function appHeader(header: Header<TFeatures, TData, any>) {
|
|
443
|
+
return header as Header<TFeatures, TData, any> & THeaderComponents
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
function appFooter(footer: Header<TFeatures, TData, any>) {
|
|
447
|
+
return footer as Header<TFeatures, TData, any> & THeaderComponents
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const appTableFeatures: TableFeature<{}> = {
|
|
451
|
+
constructTableAPIs: (table) => {
|
|
452
|
+
Object.assign(table, tableComponents, { appCell, appHeader, appFooter })
|
|
453
|
+
},
|
|
454
|
+
assignCellPrototype(prototype) {
|
|
455
|
+
Object.assign(prototype, cellComponents)
|
|
456
|
+
},
|
|
457
|
+
assignHeaderPrototype(prototype) {
|
|
458
|
+
Object.assign(prototype, headerComponents)
|
|
459
|
+
},
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return injectTable<TFeatures, TData>(() => {
|
|
463
|
+
return {
|
|
464
|
+
...defaultTableOptions,
|
|
465
|
+
...tableOptions(),
|
|
466
|
+
features: {
|
|
467
|
+
...defaultTableOptions.features,
|
|
468
|
+
appTableFeatures,
|
|
469
|
+
},
|
|
470
|
+
} as TableOptions<TFeatures, TData>
|
|
471
|
+
}) as AngularTable<any, any>
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function createAppColumnHelper<TData extends RowData>(): AppColumnHelper<
|
|
475
|
+
TFeatures,
|
|
476
|
+
TData,
|
|
477
|
+
TCellComponents,
|
|
478
|
+
THeaderComponents
|
|
479
|
+
> {
|
|
480
|
+
// The runtime implementation is the same - components are attached at render time
|
|
481
|
+
// This cast provides the enhanced types for column definitions
|
|
482
|
+
return coreCreateColumnHelper<TFeatures, TData>() as AppColumnHelper<
|
|
483
|
+
TFeatures,
|
|
484
|
+
TData,
|
|
485
|
+
TCellComponents,
|
|
486
|
+
THeaderComponents
|
|
487
|
+
>
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
return {
|
|
491
|
+
createAppColumnHelper,
|
|
492
|
+
injectTableContext,
|
|
493
|
+
injectTableHeaderContext,
|
|
494
|
+
injectTableCellContext,
|
|
495
|
+
injectFlexRenderHeaderContext,
|
|
496
|
+
injectFlexRenderCellContext,
|
|
497
|
+
injectAppTable,
|
|
498
|
+
}
|
|
499
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DestroyRef,
|
|
3
|
+
Directive,
|
|
4
|
+
Injector,
|
|
5
|
+
TemplateRef,
|
|
6
|
+
ViewContainerRef,
|
|
7
|
+
computed,
|
|
8
|
+
inject,
|
|
9
|
+
input,
|
|
10
|
+
} from '@angular/core'
|
|
11
|
+
import {
|
|
12
|
+
Cell,
|
|
13
|
+
CellData,
|
|
14
|
+
Header,
|
|
15
|
+
RowData,
|
|
16
|
+
TableFeatures,
|
|
17
|
+
} from '@tanstack/table-core'
|
|
18
|
+
import { FlexViewRenderer } from '../flex-render/renderer'
|
|
19
|
+
import type { FlexRenderInputContent } from '../flex-render/renderer'
|
|
20
|
+
import type { CellContext, HeaderContext } from '@tanstack/table-core'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Simplified directive wrapper of `*flexRender`.
|
|
24
|
+
*
|
|
25
|
+
* Use this utility component to render headers, cells, or footers with custom markup.
|
|
26
|
+
*
|
|
27
|
+
* Only one prop (`cell`, `header`, or `footer`) may be passed based on the used selector.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```html
|
|
31
|
+
* <td *flexRenderCell="cell; let cell">{{cell}}</td>
|
|
32
|
+
* <th *flexRenderHeader="header; let header">{{header}}</th>
|
|
33
|
+
* <th *flexRenderFooter="footer; let footer">{{footer}}</th>
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* This replaces calling `*flexRender` directly like this:
|
|
37
|
+
* ```html
|
|
38
|
+
* <td *flexRender="cell.column.columnDef.cell; props: cell.getContext(); let cell">{{cell}}</td>
|
|
39
|
+
* <td *flexRender="header.column.columnDef.header; props: header.getContext(); let header">{{header}}</td>
|
|
40
|
+
* <td *flexRender="footer.column.columnDef.footer; props: footer.getContext(); let footer">{{footer}}</td>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Can be imported through {@link FlexRenderCell} or {@link FlexRender} import,
|
|
44
|
+
* which the latter is preferred.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* import {FlexRender} from '@tanstack/angular-table
|
|
49
|
+
*
|
|
50
|
+
* @Component({
|
|
51
|
+
* // ...
|
|
52
|
+
* imports: [
|
|
53
|
+
* FlexRender
|
|
54
|
+
* ]
|
|
55
|
+
* })
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
@Directive({
|
|
59
|
+
selector:
|
|
60
|
+
'ng-template[flexRenderCell], ng-template[flexRenderFooter], ng-template[flexRenderHeader]',
|
|
61
|
+
})
|
|
62
|
+
export class FlexRenderCell<
|
|
63
|
+
TFeatures extends TableFeatures,
|
|
64
|
+
TData extends RowData,
|
|
65
|
+
TValue extends CellData,
|
|
66
|
+
> {
|
|
67
|
+
readonly cell = input<Cell<TFeatures, TData, TValue>>(undefined, {
|
|
68
|
+
alias: 'flexRenderCell',
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
readonly header = input<Header<TFeatures, TData, TValue>>(undefined, {
|
|
72
|
+
alias: 'flexRenderHeader',
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
readonly footer = input<Header<TFeatures, TData, TValue>>(undefined, {
|
|
76
|
+
alias: 'flexRenderFooter',
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
readonly #renderData = computed<
|
|
80
|
+
| [
|
|
81
|
+
content: FlexRenderInputContent<CellContext<TFeatures, TData, TValue>>,
|
|
82
|
+
props: CellContext<TFeatures, TData, TValue>,
|
|
83
|
+
]
|
|
84
|
+
| [
|
|
85
|
+
content: FlexRenderInputContent<
|
|
86
|
+
HeaderContext<TFeatures, TData, TValue>
|
|
87
|
+
>,
|
|
88
|
+
props: HeaderContext<TFeatures, TData, TValue>,
|
|
89
|
+
]
|
|
90
|
+
| [content: null, props: null]
|
|
91
|
+
>(
|
|
92
|
+
() => {
|
|
93
|
+
const cell = this.cell()
|
|
94
|
+
const header = this.header()
|
|
95
|
+
const footer = this.footer()
|
|
96
|
+
if (cell) {
|
|
97
|
+
return [cell.column.columnDef.cell, cell.getContext()]
|
|
98
|
+
}
|
|
99
|
+
if (header) {
|
|
100
|
+
return [header.column.columnDef.header, header.getContext()]
|
|
101
|
+
}
|
|
102
|
+
if (footer) {
|
|
103
|
+
return [footer.column.columnDef.footer, footer.getContext()]
|
|
104
|
+
}
|
|
105
|
+
return [null, null]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
equal: (a, b) => {
|
|
109
|
+
return a[0] === b[0] && a[1] === b[1]
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
readonly #injector = inject(Injector)
|
|
115
|
+
readonly #templateRef = inject(TemplateRef)
|
|
116
|
+
readonly #viewContainerRef = inject(ViewContainerRef)
|
|
117
|
+
|
|
118
|
+
constructor() {
|
|
119
|
+
const content = computed(() => this.#renderData()[0])
|
|
120
|
+
const props = computed(() => this.#renderData()[1])
|
|
121
|
+
|
|
122
|
+
const renderer = new FlexViewRenderer<TFeatures, TData, TValue, any>({
|
|
123
|
+
content: content,
|
|
124
|
+
props: props,
|
|
125
|
+
injector: () => this.#injector,
|
|
126
|
+
templateRef: this.#templateRef,
|
|
127
|
+
viewContainerRef: this.#viewContainerRef,
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
renderer.mount()
|
|
131
|
+
|
|
132
|
+
inject(DestroyRef).onDestroy(() => {
|
|
133
|
+
renderer.destroy()
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
}
|