@tanstack/angular-table 9.0.0-alpha.12 → 9.0.0-alpha.16

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.
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Type, ComponentMirror, OutputEmitterRef, InputSignal, Injector, createComponent, Binding, TemplateRef, InjectionToken, Signal, ValueEqualityFn } from '@angular/core';
3
- import { TableFeatures, RowData, CellData, Cell, Header, CellContext, HeaderContext, Table, TableFeature, TableState, TableOptions, Column, Row, AccessorFn, DeepKeys, DeepValue, IdentifiedColumnDef, AccessorFnColumnDef, AccessorKeyColumnDef, ColumnDef, DisplayColumnDef, GroupColumnDef } from '@tanstack/table-core';
3
+ import { TableFeatures, RowData, CellData, Cell, Header, CellContext, HeaderContext, TableState, Table, TableOptions, Column, Row, AccessorFn, DeepKeys, DeepValue, IdentifiedColumnDef, AccessorFnColumnDef, AccessorKeyColumnDef, ColumnDef, DisplayColumnDef, GroupColumnDef } from '@tanstack/table-core';
4
4
  export * from '@tanstack/table-core';
5
5
 
6
6
  /**
@@ -359,101 +359,19 @@ declare class FlexRenderDirective<TFeatures extends TableFeatures, TRowData exte
359
359
  static ɵdir: i0.ɵɵDirectiveDeclaration<FlexRenderDirective<any, any, any, any>, "ng-template[flexRender]", never, { "content": { "alias": "flexRender"; "required": false; "isSignal": true; }; "props": { "alias": "flexRenderProps"; "required": false; "isSignal": true; }; "injector": { "alias": "flexRenderInjector"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
360
360
  }
361
361
 
362
- declare module '@tanstack/table-core' {
363
- interface TableOptions_Plugins<TFeatures extends TableFeatures, TData extends RowData> extends TableOptions_AngularReactivity {
364
- }
365
- interface Table_Plugins<TFeatures extends TableFeatures, TData extends RowData> extends Table_AngularReactivity<TFeatures, TData> {
366
- }
367
- }
368
- /**
369
- * Predicate used to skip/ignore a property name when applying Angular reactivity.
370
- *
371
- * Returning `true` means the property should NOT be wrapped/made reactive.
372
- */
373
- type SkipPropertyFn = (property: string) => boolean;
374
- /**
375
- * Fine-grained configuration for Angular reactivity.
376
- *
377
- * Each key controls whether prototype methods/getters on the corresponding TanStack Table
378
- * objects are wrapped with signal-aware access.
379
- *
380
- * - `true` enables wrapping using the default skip rules.
381
- * - `false` disables wrapping entirely for that object type.
382
- * - a function allows customizing the skip rules (see {@link SkipPropertyFn}).
383
- *
384
- * @example
385
- * ```ts
386
- * const table = injectTable(() => {
387
- * // ...table options,
388
- * reactivity: {
389
- * // fine-grained control over which table objects have reactive properties,
390
- * // and which properties are wrapped
391
- * header: true,
392
- * column: true,
393
- * row: true,
394
- * cell: true,
395
- * }
396
- * })
397
- * ```
398
- */
399
- interface AngularReactivityFlags {
400
- /** Controls reactive wrapping for `Header` instances. */
401
- header: boolean | SkipPropertyFn;
402
- /** Controls reactive wrapping for `Column` instances. */
403
- column: boolean | SkipPropertyFn;
404
- /** Controls reactive wrapping for `Row` instances. */
405
- row: boolean | SkipPropertyFn;
406
- /** Controls reactive wrapping for `Cell` instances. */
407
- cell: boolean | SkipPropertyFn;
408
- }
409
- /**
410
- * Table option extension for Angular reactivity.
411
- *
412
- * Available on `createTable` options via module augmentation in this file.
413
- */
414
- interface TableOptions_AngularReactivity {
415
- /**
416
- * Enables/disables and configures Angular reactivity on table-related prototypes.
417
- *
418
- * If omitted, defaults are provided by the feature.
419
- */
420
- reactivity?: Partial<AngularReactivityFlags>;
421
- }
422
- /**
423
- * Table API extension for Angular reactivity.
424
- *
425
- * Added to the table instance via module augmentation.
426
- */
427
- interface Table_AngularReactivity<TFeatures extends TableFeatures, TData extends RowData> {
428
- /**
429
- * Returns a table signal that updates whenever the table state or options changes.
430
- */
431
- get: Signal<Table<TFeatures, TData>>;
432
- }
433
- /**
434
- * Type map describing what this feature adds to TanStack Table constructors.
435
- */
436
- interface AngularReactivityFeatureConstructors<TFeatures extends TableFeatures, TData extends RowData> {
437
- TableOptions: TableOptions_AngularReactivity;
438
- Table: Table_AngularReactivity<TFeatures, TData>;
439
- }
440
- /**
441
- * Angular reactivity feature that add reactive signal supports in table core instance.
442
- * This is used internally by the Angular table adapter `injectTable`.
443
- *
444
- * @private
445
- */
446
- declare const angularReactivityFeature: TableFeature<AngularReactivityFeatureConstructors<TableFeatures, RowData>>;
447
-
448
362
  type AngularTable<TFeatures extends TableFeatures, TData extends RowData, TSelected = TableState<TFeatures>> = Table<TFeatures, TData> & {
449
363
  /**
450
364
  * The selected state from the table store, based on the selector provided.
451
365
  */
452
366
  readonly state: Signal<Readonly<TSelected>>;
367
+ /**
368
+ * A signal that returns the entire table instance. Will update on table/options change.
369
+ */
370
+ readonly value: Signal<AngularTable<TFeatures, TData, TSelected>>;
453
371
  /**
454
372
  * Subscribe to changes in the table store with a custom selector.
455
373
  */
456
- Subscribe: <TSubSelected = {}>(props: {
374
+ subscribe: <TSubSelected = {}>(props: {
457
375
  selector: (state: TableState<TFeatures>) => TSubSelected;
458
376
  equal?: ValueEqualityFn<TSubSelected>;
459
377
  }) => Signal<Readonly<TSubSelected>>;
@@ -767,7 +685,7 @@ type AppGroupColumnDef<TFeatures extends TableFeatures, TData extends RowData, T
767
685
  cell?: AppColumnDefTemplate<AppCellContext<TFeatures, TData, unknown, TCellComponents>>;
768
686
  header?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
769
687
  footer?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
770
- columns?: Array<ColumnDef<TFeatures, TData, unknown>>;
688
+ columns?: ReadonlyArray<ColumnDef<TFeatures, TData, unknown>>;
771
689
  };
772
690
  /**
773
691
  * Enhanced column helper with pre-bound components in cell/header/footer contexts.
@@ -852,5 +770,5 @@ declare function createTableHook<TFeatures extends TableFeatures, const TTableCo
852
770
  */
853
771
  declare const FlexRender: readonly [typeof FlexRenderDirective, typeof FlexRenderCell];
854
772
 
855
- export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderComponentProps, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken, angularReactivityFeature, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
856
- export type { AngularReactivityFlags, AngularTable, AppAngularTable, AppCellContext, AppColumnHelper, AppHeaderContext, CreateTableContextOptions, CreateTableHookResult, FlexRenderComponent, FlexRenderContent, FlexRenderInputContent, TanStackTableCellContext, TanStackTableHeaderContext };
773
+ export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderComponentProps, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
774
+ export type { AngularTable, AppAngularTable, AppCellContext, AppColumnHelper, AppHeaderContext, CreateTableContextOptions, CreateTableHookResult, FlexRenderComponent, FlexRenderContent, FlexRenderInputContent, TanStackTableCellContext, TanStackTableHeaderContext };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/angular-table",
3
- "version": "9.0.0-alpha.12",
3
+ "version": "9.0.0-alpha.16",
4
4
  "description": "Headless UI for building powerful tables & datagrids for Angular.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -40,9 +40,9 @@
40
40
  "src"
41
41
  ],
42
42
  "dependencies": {
43
- "@tanstack/angular-store": "^0.9.1",
43
+ "@tanstack/angular-store": "^0.9.2",
44
44
  "tslib": "^2.8.1",
45
- "@tanstack/table-core": "9.0.0-alpha.12"
45
+ "@tanstack/table-core": "9.0.0-alpha.16"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@analogjs/vite-plugin-angular": "^2.2.2",
@@ -154,7 +154,7 @@ type AppGroupColumnDef<
154
154
  footer?: AppColumnDefTemplate<
155
155
  AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>
156
156
  >
157
- columns?: Array<ColumnDef<TFeatures, TData, unknown>>
157
+ columns?: ReadonlyArray<ColumnDef<TFeatures, TData, unknown>>
158
158
  }
159
159
 
160
160
  // =============================================================================
package/src/index.ts CHANGED
@@ -3,7 +3,6 @@ import { FlexRenderDirective } from './flexRender'
3
3
 
4
4
  export * from '@tanstack/table-core'
5
5
 
6
- export * from './angularReactivityFeature'
7
6
  export * from './flexRender'
8
7
  export * from './injectTable'
9
8
  export * from './flex-render/flexRenderComponent'
@@ -2,13 +2,17 @@ import {
2
2
  Injector,
3
3
  assertInInjectionContext,
4
4
  computed,
5
+ effect,
5
6
  inject,
7
+ signal,
6
8
  untracked,
7
9
  } from '@angular/core'
8
- import { constructTable } from '@tanstack/table-core'
10
+ import {
11
+ constructReactivityFeature,
12
+ constructTable,
13
+ } from '@tanstack/table-core'
9
14
  import { injectStore } from '@tanstack/angular-store'
10
15
  import { lazyInit } from './lazySignalInitializer'
11
- import { angularReactivityFeature } from './angularReactivityFeature'
12
16
  import type {
13
17
  RowData,
14
18
  Table,
@@ -27,10 +31,14 @@ export type AngularTable<
27
31
  * The selected state from the table store, based on the selector provided.
28
32
  */
29
33
  readonly state: Signal<Readonly<TSelected>>
34
+ /**
35
+ * A signal that returns the entire table instance. Will update on table/options change.
36
+ */
37
+ readonly value: Signal<AngularTable<TFeatures, TData, TSelected>>
30
38
  /**
31
39
  * Subscribe to changes in the table store with a custom selector.
32
40
  */
33
- Subscribe: <TSubSelected = {}>(props: {
41
+ subscribe: <TSubSelected = {}>(props: {
34
42
  selector: (state: TableState<TFeatures>) => TSubSelected
35
43
  equal?: ValueEqualityFn<TSubSelected>
36
44
  }) => Signal<Readonly<TSubSelected>>
@@ -103,6 +111,10 @@ export function injectTable<
103
111
  ): AngularTable<TFeatures, TData, TSelected> {
104
112
  assertInInjectionContext(injectTable)
105
113
  const injector = inject(Injector)
114
+ const stateNotifier = signal(0)
115
+ const angularReactivityFeature = constructReactivityFeature({
116
+ stateNotifier: () => stateNotifier(),
117
+ })
106
118
 
107
119
  return lazyInit(() => {
108
120
  const resolvedOptions: TableOptions<TFeatures, TData> = {
@@ -113,19 +125,22 @@ export function injectTable<
113
125
  },
114
126
  } as TableOptions<TFeatures, TData>
115
127
 
116
- const table: AngularTable<TFeatures, TData, TSelected> = constructTable(
117
- resolvedOptions,
118
- ) as AngularTable<TFeatures, TData, TSelected>
128
+ const table = constructTable(resolvedOptions) as AngularTable<
129
+ TFeatures,
130
+ TData,
131
+ TSelected
132
+ >
133
+ const tableState = injectStore(table.store, (state) => state, { injector })
134
+ const tableOptions = injectStore(table.optionsStore, (state) => state, {
135
+ injector,
136
+ })
119
137
 
120
138
  const updatedOptions = computed<TableOptions<TFeatures, TData>>(() => {
121
139
  const tableOptionsValue = options()
122
140
  const result: TableOptions<TFeatures, TData> = {
123
- ...table.options,
141
+ ...untracked(() => table.options),
124
142
  ...tableOptionsValue,
125
- _features: {
126
- ...tableOptionsValue._features,
127
- angularReactivityFeature,
128
- },
143
+ _features: { ...tableOptionsValue._features, angularReactivityFeature },
129
144
  }
130
145
  if (tableOptionsValue.state) {
131
146
  result.state = tableOptionsValue.state
@@ -133,25 +148,25 @@ export function injectTable<
133
148
  return result
134
149
  })
135
150
 
136
- const tableState = injectStore(
137
- table.store,
138
- (state: TableState<TFeatures>) => state,
139
- { injector },
151
+ effect(
152
+ () => {
153
+ const newOptions = updatedOptions()
154
+ untracked(() => table.setOptions(newOptions))
155
+ },
156
+ { injector, debugName: 'tableOptionsUpdate' },
140
157
  )
141
158
 
142
- const tableSignalNotifier = computed(
159
+ let isMount = true
160
+ effect(
143
161
  () => {
144
- tableState()
145
- table.setOptions(updatedOptions())
146
- untracked(() => table.baseStore.setState((prev) => ({ ...prev })))
147
- return table
162
+ void [tableOptions(), tableState()]
163
+ if (!isMount) untracked(() => stateNotifier.update((n) => n + 1))
164
+ isMount && (isMount = false)
148
165
  },
149
- { equal: () => false },
166
+ { injector, debugName: 'tableStateNotifier' },
150
167
  )
151
168
 
152
- table.setTableNotifier(tableSignalNotifier)
153
-
154
- table.Subscribe = function Subscribe<TSubSelected = {}>(props: {
169
+ table.subscribe = function Subscribe<TSubSelected = {}>(props: {
155
170
  selector: (state: TableState<TFeatures>) => TSubSelected
156
171
  equal?: ValueEqualityFn<TSubSelected>
157
172
  }) {
@@ -165,6 +180,14 @@ export function injectTable<
165
180
  value: injectStore(table.store, selector, { injector }),
166
181
  })
167
182
 
183
+ Object.defineProperty(table, 'value', {
184
+ value: computed(() => {
185
+ tableOptions()
186
+ tableState()
187
+ return table
188
+ }),
189
+ })
190
+
168
191
  return table
169
192
  })
170
193
  }
@@ -1,231 +0,0 @@
1
- import { computed, signal } from '@angular/core'
2
- import { setReactivePropertiesOnObject } from './reactivityUtils'
3
- import type { Signal } from '@angular/core'
4
- import type {
5
- RowData,
6
- Table,
7
- TableFeature,
8
- TableFeatures,
9
- } from '@tanstack/table-core'
10
-
11
- declare module '@tanstack/table-core' {
12
- interface TableOptions_Plugins<
13
- TFeatures extends TableFeatures,
14
- TData extends RowData,
15
- > extends TableOptions_AngularReactivity {}
16
-
17
- interface Table_Plugins<
18
- TFeatures extends TableFeatures,
19
- TData extends RowData,
20
- > extends Table_AngularReactivity<TFeatures, TData> {}
21
- }
22
-
23
- /**
24
- * Predicate used to skip/ignore a property name when applying Angular reactivity.
25
- *
26
- * Returning `true` means the property should NOT be wrapped/made reactive.
27
- */
28
- type SkipPropertyFn = (property: string) => boolean
29
-
30
- /**
31
- * Fine-grained configuration for Angular reactivity.
32
- *
33
- * Each key controls whether prototype methods/getters on the corresponding TanStack Table
34
- * objects are wrapped with signal-aware access.
35
- *
36
- * - `true` enables wrapping using the default skip rules.
37
- * - `false` disables wrapping entirely for that object type.
38
- * - a function allows customizing the skip rules (see {@link SkipPropertyFn}).
39
- *
40
- * @example
41
- * ```ts
42
- * const table = injectTable(() => {
43
- * // ...table options,
44
- * reactivity: {
45
- * // fine-grained control over which table objects have reactive properties,
46
- * // and which properties are wrapped
47
- * header: true,
48
- * column: true,
49
- * row: true,
50
- * cell: true,
51
- * }
52
- * })
53
- * ```
54
- */
55
- export interface AngularReactivityFlags {
56
- /** Controls reactive wrapping for `Header` instances. */
57
- header: boolean | SkipPropertyFn
58
- /** Controls reactive wrapping for `Column` instances. */
59
- column: boolean | SkipPropertyFn
60
- /** Controls reactive wrapping for `Row` instances. */
61
- row: boolean | SkipPropertyFn
62
- /** Controls reactive wrapping for `Cell` instances. */
63
- cell: boolean | SkipPropertyFn
64
- }
65
-
66
- /**
67
- * Table option extension for Angular reactivity.
68
- *
69
- * Available on `createTable` options via module augmentation in this file.
70
- */
71
- interface TableOptions_AngularReactivity {
72
- /**
73
- * Enables/disables and configures Angular reactivity on table-related prototypes.
74
- *
75
- * If omitted, defaults are provided by the feature.
76
- */
77
- reactivity?: Partial<AngularReactivityFlags>
78
- }
79
-
80
- /**
81
- * Table API extension for Angular reactivity.
82
- *
83
- * Added to the table instance via module augmentation.
84
- */
85
- interface Table_AngularReactivity<
86
- TFeatures extends TableFeatures,
87
- TData extends RowData,
88
- > {
89
- /**
90
- * Returns a table signal that updates whenever the table state or options changes.
91
- */
92
- get: Signal<Table<TFeatures, TData>>
93
- /**
94
- * Sets the reactive notifier that powers {@link get}.
95
- *
96
- * @internal Used by the Angular table adapter to connect its notifier to the core table.
97
- */
98
- setTableNotifier: (signal: Signal<Table<TFeatures, TData>>) => void
99
- }
100
-
101
- /**
102
- * Type map describing what this feature adds to TanStack Table constructors.
103
- */
104
- interface AngularReactivityFeatureConstructors<
105
- TFeatures extends TableFeatures,
106
- TData extends RowData,
107
- > {
108
- TableOptions: TableOptions_AngularReactivity
109
- Table: Table_AngularReactivity<TFeatures, TData>
110
- }
111
-
112
- /**
113
- * Resolves the user-provided `reactivity.*` config to a skip predicate.
114
- *
115
- * - `false` is handled by callers (feature method returns early)
116
- * - `true` selects the default predicate
117
- * - a function overrides the default predicate
118
- */
119
- const getUserSkipPropertyFn = (
120
- value: undefined | null | boolean | SkipPropertyFn,
121
- defaultPropertyFn: SkipPropertyFn,
122
- ) => {
123
- if (typeof value === 'boolean') {
124
- return defaultPropertyFn
125
- }
126
-
127
- return value ?? defaultPropertyFn
128
- }
129
-
130
- function constructAngularReactivityFeature<
131
- TFeatures extends TableFeatures,
132
- TData extends RowData,
133
- >(): TableFeature<AngularReactivityFeatureConstructors<TFeatures, TData>> {
134
- return {
135
- getDefaultTableOptions(table) {
136
- return {
137
- reactivity: {
138
- header: true,
139
- column: true,
140
- row: true,
141
- cell: true,
142
- },
143
- }
144
- },
145
- constructTableAPIs: (table) => {
146
- const rootNotifier = signal<Signal<any> | null>(null)
147
- table.setTableNotifier = (notifier) => rootNotifier.set(notifier)
148
- table.get = computed(() => rootNotifier()!(), { equal: () => false })
149
- setReactivePropertiesOnObject(table.get, table, {
150
- overridePrototype: false,
151
- skipProperty: skipBaseProperties,
152
- })
153
- },
154
-
155
- assignCellPrototype: (prototype, table) => {
156
- if (table.options.reactivity?.cell === false) {
157
- return
158
- }
159
- setReactivePropertiesOnObject(table.get, prototype, {
160
- skipProperty: getUserSkipPropertyFn(
161
- table.options.reactivity?.cell,
162
- skipBaseProperties,
163
- ),
164
- overridePrototype: true,
165
- })
166
- },
167
-
168
- assignColumnPrototype: (prototype, table) => {
169
- if (table.options.reactivity?.column === false) {
170
- return
171
- }
172
- setReactivePropertiesOnObject(table.get, prototype, {
173
- skipProperty: getUserSkipPropertyFn(
174
- table.options.reactivity?.cell,
175
- skipBaseProperties,
176
- ),
177
- overridePrototype: true,
178
- })
179
- },
180
-
181
- assignHeaderPrototype: (prototype, table) => {
182
- if (table.options.reactivity?.header === false) {
183
- return
184
- }
185
- setReactivePropertiesOnObject(table.get, prototype, {
186
- skipProperty: getUserSkipPropertyFn(
187
- table.options.reactivity?.cell,
188
- skipBaseProperties,
189
- ),
190
- overridePrototype: true,
191
- })
192
- },
193
-
194
- assignRowPrototype: (prototype, table) => {
195
- if (table.options.reactivity?.row === false) {
196
- return
197
- }
198
- setReactivePropertiesOnObject(table.get, prototype, {
199
- skipProperty: getUserSkipPropertyFn(
200
- table.options.reactivity?.cell,
201
- skipBaseProperties,
202
- ),
203
- overridePrototype: true,
204
- })
205
- },
206
- }
207
- }
208
-
209
- /**
210
- * Angular reactivity feature that add reactive signal supports in table core instance.
211
- * This is used internally by the Angular table adapter `injectTable`.
212
- *
213
- * @private
214
- */
215
- export const angularReactivityFeature = constructAngularReactivityFeature()
216
-
217
- /**
218
- * Default predicate used to skip base/non-reactive properties.
219
- */
220
- function skipBaseProperties(property: string): boolean {
221
- return (
222
- // equals `getContext`
223
- property === 'getContext' ||
224
- // start with `_`
225
- property[0] === '_' ||
226
- // doesn't start with `get`, but faster
227
- !(property[0] === 'g' && property[1] === 'e' && property[2] === 't') ||
228
- // ends with `Handler`
229
- property.endsWith('Handler')
230
- )
231
- }