@tanstack/angular-table 9.0.0-beta.4 → 9.0.0-beta.43

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 (39) hide show
  1. package/README.md +2 -0
  2. package/dist/README.md +2 -0
  3. package/dist/fesm2022/tanstack-angular-table-experimental-worker-plugin.mjs +6 -0
  4. package/dist/fesm2022/tanstack-angular-table-experimental-worker-plugin.mjs.map +1 -0
  5. package/dist/fesm2022/tanstack-angular-table.mjs +41 -21
  6. package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
  7. package/dist/types/tanstack-angular-table-experimental-worker-plugin.d.ts +1 -0
  8. package/dist/types/tanstack-angular-table.d.ts +10 -19
  9. package/package.json +13 -8
  10. package/skills/create-table-hook/SKILL.md +148 -0
  11. package/skills/getting-started/SKILL.md +138 -0
  12. package/skills/migrate-v8-to-v9/SKILL.md +194 -0
  13. package/skills/table-state/SKILL.md +197 -0
  14. package/skills/with-tanstack-query/SKILL.md +142 -0
  15. package/skills/with-tanstack-virtual/SKILL.md +126 -0
  16. package/src/flex-render/flexRenderComponent.ts +2 -2
  17. package/src/flex-render/view.ts +1 -1
  18. package/src/helpers/cell.ts +6 -2
  19. package/src/helpers/createTableHook.ts +44 -26
  20. package/src/helpers/flexRenderCell.ts +14 -0
  21. package/src/helpers/header.ts +4 -2
  22. package/src/helpers/table.ts +4 -2
  23. package/src/injectTable.ts +7 -12
  24. package/skills/angular/angular-rendering-directives/SKILL.md +0 -415
  25. package/skills/angular/angular-rendering-directives/references/content-shapes.md +0 -142
  26. package/skills/angular/angular-rendering-directives/references/create-table-hook-registries.md +0 -89
  27. package/skills/angular/angular-rendering-directives/references/di-tokens.md +0 -171
  28. package/skills/angular/angular-rendering-directives/references/flex-render-component-options.md +0 -64
  29. package/skills/angular/client-to-server/SKILL.md +0 -467
  30. package/skills/angular/compose-with-tanstack-query/SKILL.md +0 -482
  31. package/skills/angular/compose-with-tanstack-store/SKILL.md +0 -397
  32. package/skills/angular/compose-with-tanstack-virtual/SKILL.md +0 -400
  33. package/skills/angular/getting-started/SKILL.md +0 -496
  34. package/skills/angular/getting-started/references/feature-row-model-mapping.md +0 -48
  35. package/skills/angular/migrate-v8-to-v9/SKILL.md +0 -419
  36. package/skills/angular/migrate-v8-to-v9/references/v8-to-v9-mapping.md +0 -261
  37. package/skills/angular/production-readiness/SKILL.md +0 -469
  38. package/skills/angular/table-state/SKILL.md +0 -429
  39. package/skills/angular/table-state/references/external-atoms-and-app-hook.md +0 -152
@@ -144,10 +144,10 @@ interface FlexRenderOptions<TInputs extends Record<string, any>, TOutputs extend
144
144
  readonly injector?: Injector;
145
145
  }
146
146
  type Inputs<T> = {
147
- [K in keyof T as T[K] extends InputSignal<infer R> ? K : never]?: T[K] extends InputSignal<infer R> ? R : never;
147
+ [K in keyof T as T[K] extends InputSignal<infer _R> ? K : never]?: T[K] extends InputSignal<infer R> ? R : never;
148
148
  };
149
149
  type Outputs<T> = {
150
- [K in keyof T as T[K] extends OutputEmitterRef<infer R> ? K : never]?: T[K] extends OutputEmitterRef<infer R> ? OutputEmitterRef<R>['emit'] : never;
150
+ [K in keyof T as T[K] extends OutputEmitterRef<infer _R> ? K : never]?: T[K] extends OutputEmitterRef<infer R> ? OutputEmitterRef<R>['emit'] : never;
151
151
  };
152
152
  /**
153
153
  * Helper function to create a {@link FlexRenderComponent} instance, with better type-safety.
@@ -362,15 +362,7 @@ declare class FlexRenderDirective<TFeatures extends TableFeatures, TRowData exte
362
362
  }
363
363
 
364
364
  type SubscribeSource<TValue> = Atom<TValue> | ReadonlyAtom<TValue> | Store<TValue> | ReadonlyStore<TValue>;
365
- type AngularTable<TFeatures extends TableFeatures, TData extends RowData> = Table<TFeatures, TData> & {
366
- /**
367
- * @deprecated Prefer `table.atoms.<slice>.get()` for template/render reads
368
- * of a specific state slice, or Angular computed values around explicit
369
- * selectors. `table.store.state` is a current-value snapshot and is easy to
370
- * misuse in render code.
371
- */
372
- readonly store: Table<TFeatures, TData>['store'];
373
- };
365
+ type AngularTable<TFeatures extends TableFeatures, TData extends RowData> = Table<TFeatures, TData>;
374
366
  /**
375
367
  * Creates and returns an Angular-reactive table instance.
376
368
  *
@@ -444,7 +436,7 @@ interface TanStackTableCellContext<TFeatures extends TableFeatures, TData extend
444
436
  *
445
437
  * This token is provided by the {@link TanStackTableCell} directive.
446
438
  */
447
- declare const TanStackTableCellToken: InjectionToken<Signal<any>>;
439
+ declare const TanStackTableCellToken: InjectionToken<Signal<Cell<TableFeatures, RowData, unknown>>>;
448
440
  /**
449
441
  * Provides a TanStack Table `Cell` instance in Angular DI.
450
442
  *
@@ -516,7 +508,7 @@ interface TanStackTableHeaderContext<TFeatures extends TableFeatures, TData exte
516
508
  *
517
509
  * This token is provided by the {@link TanStackTableHeader} directive.
518
510
  */
519
- declare const TanStackTableHeaderToken: InjectionToken<Signal<any>>;
511
+ declare const TanStackTableHeaderToken: InjectionToken<Signal<Header<TableFeatures, RowData, unknown>>>;
520
512
  /**
521
513
  * Provides a TanStack Table `Header` instance in Angular DI.
522
514
  *
@@ -573,7 +565,7 @@ declare function injectTableHeaderContext<TFeatures extends TableFeatures, TData
573
565
  *
574
566
  * This token is provided by the {@link TanStackTable} directive.
575
567
  */
576
- declare const TanStackTableToken: InjectionToken<Signal<any>>;
568
+ declare const TanStackTableToken: InjectionToken<Signal<AngularTable<TableFeatures, RowData>>>;
577
569
  /**
578
570
  * Provides a TanStack Table instance (`AngularTable`) in Angular DI.
579
571
  *
@@ -746,12 +738,12 @@ type CreateTableContextOptions<TFeatures extends TableFeatures, TTableComponents
746
738
  };
747
739
  type CreateTableHookResult<TFeatures extends TableFeatures, TTableComponents extends Record<string, RenderableComponent>, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = {
748
740
  createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<TFeatures, TData, TCellComponents, THeaderComponents>;
749
- injectTableContext: <TData extends RowData = RowData>() => Signal<AngularTable<TFeatures, TData>>;
750
- injectTableHeaderContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Header<TFeatures, TRowData, TValue>>;
751
- injectTableCellContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Cell<TFeatures, TRowData, TValue>>;
741
+ injectTableContext: <TData extends RowData = RowData>() => Signal<AngularTable<TFeatures, TData> & TTableComponents>;
742
+ injectTableHeaderContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Header<TFeatures, TRowData, TValue> & THeaderComponents>;
743
+ injectTableCellContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Cell<TFeatures, TRowData, TValue> & TCellComponents>;
752
744
  injectFlexRenderHeaderContext: <TData extends RowData, TValue extends CellData>() => HeaderContext<TFeatures, TData, TValue>;
753
745
  injectFlexRenderCellContext: <TData extends RowData, TValue extends CellData>() => CellContext<TFeatures, TData, TValue>;
754
- injectAppTable: <TData extends RowData>(tableOptions: () => Omit<TableOptions<TFeatures, TData>, 'features' | 'rowModels'>) => AppAngularTable<TFeatures, TData, TTableComponents, TCellComponents, THeaderComponents>;
746
+ injectAppTable: <TData extends RowData>(tableOptions: () => Omit<TableOptions<TFeatures, TData>, 'features'>) => AppAngularTable<TFeatures, TData, TTableComponents, TCellComponents, THeaderComponents>;
755
747
  };
756
748
  /**
757
749
  * Creates app-scoped Angular table helpers with features, row models, and
@@ -765,7 +757,6 @@ type CreateTableHookResult<TFeatures extends TableFeatures, TTableComponents ext
765
757
  * ```ts
766
758
  * const { injectAppTable, createAppColumnHelper } = createTableHook({
767
759
  * features,
768
- * rowModels: {},
769
760
  * tableComponents: {},
770
761
  * cellComponents: {},
771
762
  * headerComponents: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/angular-table",
3
- "version": "9.0.0-beta.4",
3
+ "version": "9.0.0-beta.43",
4
4
  "description": "Headless UI for building powerful tables & datagrids for Angular.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -33,6 +33,10 @@
33
33
  "types": "./dist/types/tanstack-angular-table-static-functions.d.ts",
34
34
  "default": "./dist/fesm2022/tanstack-angular-table-static-functions.mjs"
35
35
  },
36
+ "./experimental-worker-plugin": {
37
+ "types": "./dist/types/tanstack-angular-table-experimental-worker-plugin.d.ts",
38
+ "default": "./dist/fesm2022/tanstack-angular-table-experimental-worker-plugin.mjs"
39
+ },
36
40
  "./flex-render": {
37
41
  "types": "./dist/types/tanstack-angular-table.d.ts",
38
42
  "default": "./dist/fesm2022/tanstack-angular-table.mjs"
@@ -42,7 +46,7 @@
42
46
  }
43
47
  },
44
48
  "engines": {
45
- "node": ">=18"
49
+ "node": ">=20"
46
50
  },
47
51
  "files": [
48
52
  "dist",
@@ -52,14 +56,15 @@
52
56
  ],
53
57
  "dependencies": {
54
58
  "@tanstack/angular-store": "^0.11.0",
55
- "@tanstack/table-core": "^9.0.0-beta.2",
56
- "tslib": "^2.8.1"
59
+ "tslib": "^2.8.1",
60
+ "@tanstack/table-core": "9.0.0-beta.43"
57
61
  },
58
62
  "devDependencies": {
59
- "@analogjs/vite-plugin-angular": "^2.6.0",
60
- "@analogjs/vitest-angular": "^2.6.0",
61
- "@angular/core": "^22.0.0",
62
- "@angular/platform-browser": "^22.0.0",
63
+ "@analogjs/vite-plugin-angular": "^2.6.1",
64
+ "@analogjs/vitest-angular": "^2.6.1",
65
+ "@angular/compiler": "^22.0.2",
66
+ "@angular/core": "^22.0.2",
67
+ "@angular/platform-browser": "^22.0.2",
63
68
  "ng-packagr": "^22.0.0",
64
69
  "typescript": "6.0.3"
65
70
  },
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: create-table-hook
3
+ description: >
4
+ Create an Angular injectAppTable/createAppColumnHelper abstraction with shared features/defaults, registered components, injectTableContext/injectTableCellContext/injectTableHeaderContext, and correct FlexRender component-versus-function handling.
5
+ metadata:
6
+ type: framework
7
+ library: '@tanstack/angular-table'
8
+ framework: angular
9
+ library_version: '9.0.0-beta.43'
10
+ requires:
11
+ - '@tanstack/table-core#core'
12
+ - getting-started
13
+ - table-state
14
+ sources:
15
+ - 'TanStack/table:docs/framework/angular/guide/composable-tables.md'
16
+ - 'TanStack/table:examples/angular/composable-tables'
17
+ - 'TanStack/table:packages/angular-table/src/helpers/createTableHook.ts'
18
+ ---
19
+
20
+ This skill builds on `@tanstack/table-core#core`, `getting-started`, and `table-state`. Use it for repeated app conventions; keep one-off tables on `injectTable`.
21
+
22
+ ## Setup
23
+
24
+ ```ts
25
+ import {
26
+ createTableHook,
27
+ rowSortingFeature,
28
+ tableFeatures,
29
+ } from '@tanstack/angular-table'
30
+
31
+ export const {
32
+ injectAppTable,
33
+ createAppColumnHelper,
34
+ injectTableContext,
35
+ injectTableCellContext,
36
+ injectTableHeaderContext,
37
+ } = createTableHook({
38
+ features: tableFeatures({ rowSortingFeature }),
39
+ })
40
+ ```
41
+
42
+ ```ts
43
+ const helper = createAppColumnHelper<Person>()
44
+ const columns = helper.columns([helper.accessor('name', { header: 'Name' })])
45
+
46
+ export class PeopleTable {
47
+ readonly table = injectAppTable(() => ({ columns, data: this.data() }))
48
+ }
49
+ ```
50
+
51
+ ## Core Patterns
52
+
53
+ ### Consume typed DI context in registered components
54
+
55
+ ```ts
56
+ export class NameCell {
57
+ readonly cell = injectTableCellContext<string, Person>()
58
+ readonly value = computed(() => this.cell().getValue())
59
+ }
60
+ ```
61
+
62
+ Use the matching table/header/cell injector instead of threading context props through reusable components.
63
+
64
+ ### Distinguish component types from render functions
65
+
66
+ Register either an Angular component type or a render function. Return component types directly when FlexRender should set context inputs; use `flexRenderComponent(Component, options)` only for explicit inputs/outputs/injector/bindings/directives.
67
+
68
+ ## Common Mistakes
69
+
70
+ ### CRITICAL Calling app helpers outside DI
71
+
72
+ Wrong:
73
+
74
+ ```ts
75
+ export function make() {
76
+ return injectAppTable(() => options)
77
+ }
78
+ ```
79
+
80
+ Correct:
81
+
82
+ ```ts
83
+ export class PeopleTable {
84
+ readonly table = injectAppTable(() => options())
85
+ }
86
+ ```
87
+
88
+ Both app-table construction and returned context injectors require Angular injection context.
89
+
90
+ Source: `packages/angular-table/src/helpers/createTableHook.ts`
91
+
92
+ ### HIGH Prop drilling registered context
93
+
94
+ Wrong:
95
+
96
+ ```ts
97
+ cell: (ctx) => flexRenderComponent(NameCell, { inputs: { cell: ctx.cell } })
98
+ ```
99
+
100
+ Correct:
101
+
102
+ ```ts
103
+ cell: (ctx) => ctx.cell.NameCell
104
+ ```
105
+
106
+ Registered components can consume the app hook’s typed cell context directly.
107
+
108
+ Source: `docs/framework/angular/guide/composable-tables.md`
109
+
110
+ ### HIGH Wrapping a function as a component
111
+
112
+ Wrong:
113
+
114
+ ```ts
115
+ flexRenderComponent((props) => props.cell.getValue())
116
+ ```
117
+
118
+ Correct:
119
+
120
+ ```ts
121
+ ;(props) => props.cell.getValue()
122
+ ```
123
+
124
+ `flexRenderComponent` validates an Angular component type; plain render functions are already valid render content.
125
+
126
+ Source: `packages/angular-table/src/flex-render/flexRenderComponent.ts`
127
+
128
+ ### MEDIUM Abstracting a one-off table
129
+
130
+ Wrong:
131
+
132
+ ```ts
133
+ const hook = createTableHook({ features: tableFeatures({}) })
134
+ ```
135
+
136
+ Correct:
137
+
138
+ ```ts
139
+ readonly table = injectTable(() => ({ features, columns, data: this.data() }))
140
+ ```
141
+
142
+ Use the app hook only when shared defaults, types, or registered components justify it.
143
+
144
+ Source: `docs/framework/angular/guide/composable-tables.md`
145
+
146
+ ## API Discovery
147
+
148
+ Inspect `node_modules/@tanstack/angular-table/src/helpers/createTableHook.ts`, `helpers/{table,cell,header}.ts`, and `flex-render/` for exact DI and rendering contracts.
@@ -0,0 +1,138 @@
1
+ ---
2
+ name: getting-started
3
+ description: >
4
+ Create an Angular TanStack Table v9 table with injectTable inside injection context, explicit stable tableFeatures and columns, signal-backed data, and FlexRender structural directives or helpers.
5
+ metadata:
6
+ type: framework
7
+ library: '@tanstack/angular-table'
8
+ framework: angular
9
+ library_version: '9.0.0-beta.43'
10
+ requires:
11
+ - '@tanstack/table-core#core'
12
+ - '@tanstack/table-core#table-features'
13
+ sources:
14
+ - 'TanStack/table:docs/framework/angular/guide/migrating.md'
15
+ - 'TanStack/table:docs/framework/angular/guide/rendering.md'
16
+ - 'TanStack/table:examples/angular/basic-inject-table'
17
+ - 'TanStack/table:packages/angular-table/src/index.ts'
18
+ ---
19
+
20
+ This skill builds on `@tanstack/table-core#core` and `@tanstack/table-core#table-features`. Read them first for the headless model and explicit features.
21
+
22
+ ## Setup
23
+
24
+ ```ts
25
+ import { Component, signal } from '@angular/core'
26
+ import { FlexRender, injectTable, tableFeatures } from '@tanstack/angular-table'
27
+
28
+ type Person = { name: string; age: number }
29
+ const features = tableFeatures({})
30
+ const columns = [
31
+ { accessorKey: 'name', header: 'Name' },
32
+ { accessorKey: 'age', header: 'Age' },
33
+ ]
34
+
35
+ @Component({
36
+ selector: 'app-table',
37
+ imports: [FlexRender],
38
+ template: `<table>
39
+ <tbody>
40
+ @for (row of table.getRowModel().rows; track row.id) {
41
+ <tr>
42
+ @for (cell of row.getAllCells(); track cell.id) {
43
+ <td>
44
+ <ng-container *flexRenderCell="cell; let value">{{
45
+ value
46
+ }}</ng-container>
47
+ </td>
48
+ }
49
+ </tr>
50
+ }
51
+ </tbody>
52
+ </table>`,
53
+ })
54
+ export class TableComponent {
55
+ readonly data = signal<Person[]>([{ name: 'Ada', age: 36 }])
56
+ readonly table = injectTable(() => ({ features, columns, data: this.data() }))
57
+ }
58
+ ```
59
+
60
+ ## Core Patterns
61
+
62
+ ### Keep static inputs outside the initializer
63
+
64
+ `injectTable` reruns its options initializer when a signal read changes. Define features, row-model factories, and columns at module or stable class scope; read only changing values inside.
65
+
66
+ ### Render each content kind correctly
67
+
68
+ Import `FlexRender` for `*flexRender`, `*flexRenderCell`, `*flexRenderHeader`, and `*flexRenderFooter`. Definitions may yield primitives, `TemplateRef`, component types, or `flexRenderComponent(...)`; Table does not supply markup or CSS.
69
+
70
+ ## Common Mistakes
71
+
72
+ ### CRITICAL Calling injectTable outside DI
73
+
74
+ Wrong:
75
+
76
+ ```ts
77
+ export function makeTable() {
78
+ return injectTable(() => ({ features, columns, data }))
79
+ }
80
+ ```
81
+
82
+ Correct:
83
+
84
+ ```ts
85
+ export class TableComponent {
86
+ readonly table = injectTable(() => ({ features, columns, data: this.data() }))
87
+ }
88
+ ```
89
+
90
+ `injectTable` asserts an Angular injection context and registers lifecycle cleanup there.
91
+
92
+ Source: `packages/angular-table/src/injectTable.ts`
93
+
94
+ ### HIGH Reallocating static options reactively
95
+
96
+ Wrong:
97
+
98
+ ```ts
99
+ injectTable(() => ({
100
+ features: tableFeatures({}),
101
+ columns: makeColumns(),
102
+ data: this.data(),
103
+ }))
104
+ ```
105
+
106
+ Correct:
107
+
108
+ ```ts
109
+ const features = tableFeatures({})
110
+ const columns = makeColumns()
111
+ injectTable(() => ({ features, columns, data: this.data() }))
112
+ ```
113
+
114
+ Every signal change reruns the initializer; rebuilding static inputs invalidates memoized Table work.
115
+
116
+ Source: `packages/angular-table/src/injectTable.ts`
117
+
118
+ ### HIGH Treating a render function as a component
119
+
120
+ Wrong:
121
+
122
+ ```ts
123
+ cell: () => flexRenderComponent(() => 'value')
124
+ ```
125
+
126
+ Correct:
127
+
128
+ ```ts
129
+ cell: () => 'value'
130
+ ```
131
+
132
+ `flexRenderComponent` wraps an Angular component type; ordinary functions and primitives are handled directly by FlexRender.
133
+
134
+ Source: `docs/framework/angular/guide/rendering.md`
135
+
136
+ ## API Discovery
137
+
138
+ Inspect `node_modules/@tanstack/angular-table/src/index.ts`, `injectTable.ts`, `flexRender.ts`, and `flex-render/`; inspect optional feature APIs in installed `@tanstack/table-core/src/features/`.
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: migrate-v8-to-v9
3
+ description: >
4
+ Complete Angular v8-to-v9 migration reference: injectTable and injection context, explicit features and row-model slots, signal/atom state, FlexRender directives, type generics, prototype methods, sorting, sizing, selection, and logical pinning.
5
+ metadata:
6
+ type: lifecycle
7
+ library: '@tanstack/angular-table'
8
+ framework: angular
9
+ library_version: '9.0.0-beta.43'
10
+ requires:
11
+ - '@tanstack/table-core#migrate-v8-to-v9'
12
+ - getting-started
13
+ - table-state
14
+ sources:
15
+ - 'TanStack/table:docs/framework/angular/guide/migrating.md'
16
+ - 'TanStack/table:packages/angular-table/src/index.ts'
17
+ - 'TanStack/table:examples/angular/basic-inject-table'
18
+ ---
19
+
20
+ Use this as the complete breaking-change checklist. V9 is the current API; construction, feature registration, state, rendering, and types must migrate together.
21
+
22
+ Framework prerequisite: Angular 19 or newer (`@angular/core >=19`).
23
+
24
+ ## Recommended Migration Order
25
+
26
+ 1. Replace `createAngularTable` with `injectTable` inside an Angular injection context.
27
+ 2. Hoist static/expensive features and columns outside the reactive initializer.
28
+ 3. Move features, row models, and function registries into `tableFeatures`.
29
+ 4. Update signal/atom state reads and FlexRender usage.
30
+ 5. Apply every shared API and type rename below.
31
+ 6. Treat `stockFeatures` as a temporary audit bridge; explicit features are the production target.
32
+
33
+ ```ts
34
+ const features = tableFeatures({
35
+ rowSortingFeature,
36
+ sortedRowModel: createSortedRowModel(),
37
+ sortFns,
38
+ })
39
+
40
+ class TableCmp {
41
+ readonly table = injectTable(() => ({
42
+ features,
43
+ columns,
44
+ data: this.data(),
45
+ }))
46
+ }
47
+ ```
48
+
49
+ ## Construction and Feature Registration
50
+
51
+ | v8 | v9 |
52
+ | ----------------------------------- | ---------------------------------------------------------- |
53
+ | `createAngularTable(() => options)` | `injectTable(() => options)` in injection context |
54
+ | All features bundled | Required `features: tableFeatures({...})` |
55
+ | `getCoreRowModel()` option | Remove; core row model is automatic |
56
+ | `get*RowModel()` table options | `create*RowModel()` slots in `tableFeatures` |
57
+ | `sortingFns` table option | `sortFns` feature slot |
58
+ | Top-level `onStateChange` | Per-slice callbacks, external atoms, or store subscription |
59
+
60
+ The initializer reruns when signals read inside it change and calls `setOptions`; do not rebuild columns or features there.
61
+
62
+ Feature imports are `columnFilteringFeature`, `globalFilteringFeature`, `rowSortingFeature`, `rowPaginationFeature`, `rowSelectionFeature`, `rowExpandingFeature`, `rowPinningFeature`, `columnPinningFeature`, `columnVisibilityFeature`, `columnOrderingFeature`, `columnSizingFeature`, `columnResizingFeature`, `columnGroupingFeature`, and `columnFacetingFeature`. APIs are feature-gated. Put a feature before its dependent slot in the same `tableFeatures` call.
63
+
64
+ ### Row-model mapping
65
+
66
+ | v8 option | v9 slot and factory |
67
+ | -------------------------- | ------------------------------------------------------------------- |
68
+ | `getFilteredRowModel()` | `filteredRowModel: createFilteredRowModel()` after column filtering |
69
+ | `getSortedRowModel()` | `sortedRowModel: createSortedRowModel()` after row sorting |
70
+ | `getPaginationRowModel()` | `paginatedRowModel: createPaginatedRowModel()` after pagination |
71
+ | `getExpandedRowModel()` | `expandedRowModel: createExpandedRowModel()` after expanding |
72
+ | `getGroupedRowModel()` | `groupedRowModel: createGroupedRowModel()` after grouping |
73
+ | `getFacetedRowModel()` | `facetedRowModel: createFacetedRowModel()` after faceting |
74
+ | `getFacetedMinMaxValues()` | `facetedMinMaxValues: createFacetedMinMaxValues()` |
75
+ | `getFacetedUniqueValues()` | `facetedUniqueValues: createFacetedUniqueValues()` |
76
+
77
+ Factories take no arguments. `filterFns`, `sortFns`, and `aggregationFns` are sibling feature slots.
78
+
79
+ ## Angular State Migration
80
+
81
+ - `table.getState().sorting` becomes `table.atoms.sorting.get()` for narrow signal-backed reads.
82
+ - Use `table.store.get()` only for a full flat snapshot/debug output.
83
+ - Derive selected slices with Angular `computed`; use `shallow` equality for recreated object/array slices when appropriate.
84
+ - Controlled Angular signals are read in `state` and updated through matching `on[State]Change` callbacks; resolve value-or-function updaters.
85
+ - Top-level `onStateChange` is removed. Use per-slice callbacks, external atoms, or `table.store.subscribe` for all changes.
86
+ - Prefer external atoms from `@tanstack/angular-store` through `atoms` for app-owned shared slices. Never provide both an atom and `state` for one slice.
87
+ - Treat `table.baseAtoms` as internal; prefer feature APIs or external atoms.
88
+
89
+ ## Angular Rendering and Composition
90
+
91
+ - Import `FlexRender`/the current `*flexRender` directives from the adapter.
92
+ - Prefer `*flexRenderCell="cell; let value"`, `*flexRenderHeader="header; let value"`, and `*flexRenderFooter="footer; let value"`; they choose the definition and context automatically.
93
+ - General `*flexRender` supports primitives, `TemplateRef`, component types, and `flexRenderComponent(...)` wrappers.
94
+ - Column render functions run in an Angular injection context and may call `inject()` or use signals.
95
+ - Components mounted by FlexRender can call `injectFlexRenderContext()` for the render props.
96
+ - Use `flexRenderComponent(Component, { inputs, outputs, injector, bindings, directives })` for explicit component configuration; creation-time `bindings`/`directives` require the supported Angular version.
97
+ - `tableOptions(...)` composes partial options and may omit data, columns, or features until final assembly.
98
+ - `createTableHook` is optional for repeated application conventions; it returns `injectAppTable` and a feature-bound `createAppColumnHelper`.
99
+
100
+ ## Complete Shared Breaking-Change Map
101
+
102
+ ### Instance methods
103
+
104
+ Row, cell, column, header, and related methods now live on shared prototypes and use `this`. Call them on their instances. Do not destructure/pass them bare or expect them in object spread, `Object.keys`, or JSON. Table methods are not affected.
105
+
106
+ ### Logical column pinning
107
+
108
+ Beta.38 has no physical aliases.
109
+
110
+ | old | new |
111
+ | -------------------------------------------------------------- | ------------------------------------------------------------- |
112
+ | `columnPinning.left` / `.right` | `.start` / `.end` |
113
+ | `column.pin('left' \| 'right')` | `column.pin('start' \| 'end')` |
114
+ | `getIsPinned() === 'left' \| 'right'` | `'start' \| 'end'` |
115
+ | `row.getLeftVisibleCells()` / `getRightVisibleCells()` | `getStartVisibleCells()` / `getEndVisibleCells()` |
116
+ | `getLeftHeaderGroups()` / `getRightHeaderGroups()` | `getStartHeaderGroups()` / `getEndHeaderGroups()` |
117
+ | `getLeftFooterGroups()` / `getRightFooterGroups()` | `getStartFooterGroups()` / `getEndFooterGroups()` |
118
+ | `getLeftFlatHeaders()` / `getRightFlatHeaders()` | `getStartFlatHeaders()` / `getEndFlatHeaders()` |
119
+ | `getLeftLeafHeaders()` / `getRightLeafHeaders()` | `getStartLeafHeaders()` / `getEndLeafHeaders()` |
120
+ | `getLeftLeafColumns()` / `getRightLeafColumns()` | `getStartLeafColumns()` / `getEndLeafColumns()` |
121
+ | `getLeftVisibleLeafColumns()` / `getRightVisibleLeafColumns()` | `getStartVisibleLeafColumns()` / `getEndVisibleLeafColumns()` |
122
+ | `getLeftTotalSize()` / `getRightTotalSize()` | `getStartTotalSize()` / `getEndTotalSize()` |
123
+ | `column.getStart('left')` | `column.getStart('start')` |
124
+ | `column.getAfter('right')` | `column.getAfter('end')` |
125
+ | `column.getIndex('left' \| 'right')` | `column.getIndex('start' \| 'end')` |
126
+
127
+ Prefer CSS logical inset properties. Logical names do not set DOM direction. `columnResizeDirection` is unchanged.
128
+
129
+ ### Pinning, sizing, and resizing
130
+
131
+ - `enablePinning` splits into `enableColumnPinning` and `enableRowPinning`.
132
+ - Interactive resizing requires `columnSizingFeature` and `columnResizingFeature`; fixed sizing needs only sizing.
133
+ - `columnSizingInfo` becomes `columnResizing`.
134
+ - `setColumnSizingInfo()` becomes `setColumnResizing()`.
135
+ - `onColumnSizingInfoChange` becomes `onColumnResizingChange`.
136
+
137
+ ### Sorting, rows, and selection
138
+
139
+ | v8 | v9 |
140
+ | ------------------------------ | ----------------------------- |
141
+ | `sortingFn` | `sortFn` |
142
+ | `sortingFns` | `sortFns` |
143
+ | `getSortingFn()` | `getSortFn()` |
144
+ | `getAutoSortingFn()` | `getAutoSortFn()` |
145
+ | `SortingFn` / `SortingFns` | `SortFn` / `SortFns` |
146
+ | `row._getAllCellsByColumnId()` | `row.getAllCellsByColumnId()` |
147
+
148
+ Other `_`-prefixed internals are removed, including `_getPinnedRows`, `_getFacetedRowModel`, `_getFacetedMinMaxValues`, and `_getFacetedUniqueValues`.
149
+
150
+ `getIsSomeRowsSelected()` and `getIsSomePageRowsSelected()` mean at least one, including all. Use `getIsSomeRowsSelected() && !getIsAllRowsSelected()` or `getIsSomePageRowsSelected() && !getIsAllPageRowsSelected()` for indeterminate UI.
151
+
152
+ ## TypeScript Migration
153
+
154
+ - Most types add `TFeatures` first: `Column<TFeatures, TData, TValue>`, `ColumnDef<TFeatures, TData, TValue>`, `Table<TFeatures, TData>`, `Row<TFeatures, TData>`, and `Cell<TFeatures, TData, TValue>`.
155
+ - Replace `createColumnHelper<Person>()` with `createColumnHelper<typeof features, Person>()`; use `columnHelper.columns([...])` for inference.
156
+ - A `createTableHook` column helper already binds features and needs only `<Person>`.
157
+ - Use `StockFeatures` when using `stockFeatures`.
158
+ - Existing `TableMeta`/`ColumnMeta` declaration merging must add `TFeatures` first. Prefer per-table meta slots using `metaHelper`.
159
+ - Replace global `FilterFns`, `SortFns`, `AggregationFns`, and `FilterMeta` augmentation with registry slots and `filterMeta`; registered keys become typed string references.
160
+ - `RowData` is now `Record<string, any> | Array<any>` rather than `unknown`.
161
+
162
+ ## Common Migration Failures
163
+
164
+ ### CRITICAL: Calling injectTable outside injection context
165
+
166
+ Create it in a component/directive/service field initializer or another valid Angular injection context so ownership and cleanup bind correctly.
167
+
168
+ ### HIGH: Rebuilding static inputs reactively
169
+
170
+ Hoist `features` and `columns`; the initializer reruns for tracked signals.
171
+
172
+ ### HIGH: Leaving row models on table options
173
+
174
+ Move each row model beside its prerequisite feature in `tableFeatures`.
175
+
176
+ ### HIGH: Destructuring instance methods
177
+
178
+ Use `row.getValue('name')`; prototype methods require the original instance and are absent from shallow clones.
179
+
180
+ ## Final Checklist
181
+
182
+ - [ ] `createAngularTable` is replaced by `injectTable` in injection context.
183
+ - [ ] Static inputs are stable outside the signal-tracked initializer.
184
+ - [ ] Features, row models, and registries are in `tableFeatures`; core row model is removed.
185
+ - [ ] State reads use atom-backed signals or store intentionally; `onStateChange` is gone.
186
+ - [ ] Controlled state and external atom ownership do not overlap.
187
+ - [ ] FlexRender directives/helpers are migrated and imported.
188
+ - [ ] Prototype methods, pinning, sizing/resizing, sorting, row, and selection changes are audited.
189
+ - [ ] Helpers, types, meta, registries, and `RowData` use v9 shapes.
190
+ - [ ] Temporary `stockFeatures` usage has an explicit removal plan.
191
+
192
+ ## API Discovery
193
+
194
+ Inspect `node_modules/@tanstack/angular-table/src/index.ts`, `injectTable.ts`, and rendering sources. Verify feature slots and exact beta APIs in `node_modules/@tanstack/table-core/src`; do not reconstruct v9 from v8 memory.