@tanstack/angular-table 9.0.0-alpha.13 → 9.0.0-alpha.17

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,20 @@ 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>>;
453
367
  /**
454
- * Subscribe to changes in the table store with a custom selector.
368
+ * A signal that returns the entire table instance. Will update on table/options change.
369
+ */
370
+ readonly value: Signal<AngularTable<TFeatures, TData, TSelected>>;
371
+ /**
372
+ * Creates a computed that subscribe to changes in the table store with a custom selector.
373
+ * Default equality function is "shallow".
455
374
  */
456
- Subscribe: <TSubSelected = {}>(props: {
375
+ computed: <TSubSelected = {}>(props: {
457
376
  selector: (state: TableState<TFeatures>) => TSubSelected;
458
377
  equal?: ValueEqualityFn<TSubSelected>;
459
378
  }) => Signal<Readonly<TSubSelected>>;
@@ -852,5 +771,5 @@ declare function createTableHook<TFeatures extends TableFeatures, const TTableCo
852
771
  */
853
772
  declare const FlexRender: readonly [typeof FlexRenderDirective, typeof FlexRenderCell];
854
773
 
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 };
774
+ export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderComponentProps, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
775
+ 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.13",
3
+ "version": "9.0.0-alpha.17",
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.13"
45
+ "@tanstack/table-core": "9.0.0-alpha.16"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@analogjs/vite-plugin-angular": "^2.2.2",
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,
@@ -28,9 +32,14 @@ export type AngularTable<
28
32
  */
29
33
  readonly state: Signal<Readonly<TSelected>>
30
34
  /**
31
- * Subscribe to changes in the table store with a custom selector.
35
+ * A signal that returns the entire table instance. Will update on table/options change.
36
+ */
37
+ readonly value: Signal<AngularTable<TFeatures, TData, TSelected>>
38
+ /**
39
+ * Creates a computed that subscribe to changes in the table store with a custom selector.
40
+ * Default equality function is "shallow".
32
41
  */
33
- Subscribe: <TSubSelected = {}>(props: {
42
+ computed: <TSubSelected = {}>(props: {
34
43
  selector: (state: TableState<TFeatures>) => TSubSelected
35
44
  equal?: ValueEqualityFn<TSubSelected>
36
45
  }) => Signal<Readonly<TSubSelected>>
@@ -103,6 +112,10 @@ export function injectTable<
103
112
  ): AngularTable<TFeatures, TData, TSelected> {
104
113
  assertInInjectionContext(injectTable)
105
114
  const injector = inject(Injector)
115
+ const stateNotifier = signal(0)
116
+ const angularReactivityFeature = constructReactivityFeature({
117
+ stateNotifier: () => stateNotifier(),
118
+ })
106
119
 
107
120
  return lazyInit(() => {
108
121
  const resolvedOptions: TableOptions<TFeatures, TData> = {
@@ -113,19 +126,22 @@ export function injectTable<
113
126
  },
114
127
  } as TableOptions<TFeatures, TData>
115
128
 
116
- const table: AngularTable<TFeatures, TData, TSelected> = constructTable(
117
- resolvedOptions,
118
- ) as AngularTable<TFeatures, TData, TSelected>
129
+ const table = constructTable(resolvedOptions) as AngularTable<
130
+ TFeatures,
131
+ TData,
132
+ TSelected
133
+ >
134
+ const tableState = injectStore(table.store, (state) => state, { injector })
135
+ const tableOptions = injectStore(table.optionsStore, (state) => state, {
136
+ injector,
137
+ })
119
138
 
120
139
  const updatedOptions = computed<TableOptions<TFeatures, TData>>(() => {
121
140
  const tableOptionsValue = options()
122
141
  const result: TableOptions<TFeatures, TData> = {
123
- ...table.options,
142
+ ...untracked(() => table.options),
124
143
  ...tableOptionsValue,
125
- _features: {
126
- ...tableOptionsValue._features,
127
- angularReactivityFeature,
128
- },
144
+ _features: { ...tableOptionsValue._features, angularReactivityFeature },
129
145
  }
130
146
  if (tableOptionsValue.state) {
131
147
  result.state = tableOptionsValue.state
@@ -133,25 +149,25 @@ export function injectTable<
133
149
  return result
134
150
  })
135
151
 
136
- const tableState = injectStore(
137
- table.store,
138
- (state: TableState<TFeatures>) => state,
139
- { injector },
152
+ effect(
153
+ () => {
154
+ const newOptions = updatedOptions()
155
+ untracked(() => table.setOptions(newOptions))
156
+ },
157
+ { injector, debugName: 'tableOptionsUpdate' },
140
158
  )
141
159
 
142
- const tableSignalNotifier = computed(
160
+ let isMount = true
161
+ effect(
143
162
  () => {
144
- tableState()
145
- table.setOptions(updatedOptions())
146
- untracked(() => table.baseStore.setState((prev) => ({ ...prev })))
147
- return table
163
+ void [tableOptions(), tableState()]
164
+ if (!isMount) untracked(() => stateNotifier.update((n) => n + 1))
165
+ isMount && (isMount = false)
148
166
  },
149
- { equal: () => false },
167
+ { injector, debugName: 'tableStateNotifier' },
150
168
  )
151
169
 
152
- table.setTableNotifier(tableSignalNotifier)
153
-
154
- table.Subscribe = function Subscribe<TSubSelected = {}>(props: {
170
+ table.computed = function Subscribe<TSubSelected = {}>(props: {
155
171
  selector: (state: TableState<TFeatures>) => TSubSelected
156
172
  equal?: ValueEqualityFn<TSubSelected>
157
173
  }) {
@@ -165,6 +181,14 @@ export function injectTable<
165
181
  value: injectStore(table.store, selector, { injector }),
166
182
  })
167
183
 
184
+ Object.defineProperty(table, 'value', {
185
+ value: computed(() => {
186
+ tableOptions()
187
+ tableState()
188
+ return table
189
+ }),
190
+ })
191
+
168
192
  return table
169
193
  })
170
194
  }
@@ -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
- }