@tanstack/table-core 9.0.0-beta.37 → 9.0.0-beta.42

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 (100) hide show
  1. package/README.md +1 -0
  2. package/dist/core/headers/buildHeaderGroups.cjs.map +1 -1
  3. package/dist/core/headers/buildHeaderGroups.d.cts +1 -1
  4. package/dist/core/headers/buildHeaderGroups.d.ts +1 -1
  5. package/dist/core/headers/buildHeaderGroups.js.map +1 -1
  6. package/dist/core/headers/coreHeadersFeature.utils.cjs +7 -7
  7. package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
  8. package/dist/core/headers/coreHeadersFeature.utils.js +7 -7
  9. package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
  10. package/dist/core/table/coreTablesFeature.utils.cjs +1 -1
  11. package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
  12. package/dist/core/table/coreTablesFeature.utils.js +1 -1
  13. package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
  14. package/dist/features/column-ordering/columnOrderingFeature.types.d.cts +5 -5
  15. package/dist/features/column-ordering/columnOrderingFeature.types.d.ts +5 -5
  16. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +6 -6
  17. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
  18. package/dist/features/column-ordering/columnOrderingFeature.utils.d.cts +3 -3
  19. package/dist/features/column-ordering/columnOrderingFeature.utils.d.ts +3 -3
  20. package/dist/features/column-ordering/columnOrderingFeature.utils.js +6 -6
  21. package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
  22. package/dist/features/column-pinning/columnPinningFeature.cjs +44 -39
  23. package/dist/features/column-pinning/columnPinningFeature.cjs.map +1 -1
  24. package/dist/features/column-pinning/columnPinningFeature.d.cts +6 -1
  25. package/dist/features/column-pinning/columnPinningFeature.d.ts +6 -1
  26. package/dist/features/column-pinning/columnPinningFeature.js +45 -40
  27. package/dist/features/column-pinning/columnPinningFeature.js.map +1 -1
  28. package/dist/features/column-pinning/columnPinningFeature.types.d.cts +49 -38
  29. package/dist/features/column-pinning/columnPinningFeature.types.d.ts +49 -38
  30. package/dist/features/column-pinning/columnPinningFeature.utils.cjs +154 -146
  31. package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
  32. package/dist/features/column-pinning/columnPinningFeature.utils.d.cts +81 -73
  33. package/dist/features/column-pinning/columnPinningFeature.utils.d.ts +81 -73
  34. package/dist/features/column-pinning/columnPinningFeature.utils.js +141 -133
  35. package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
  36. package/dist/features/column-sizing/columnSizingFeature.cjs +4 -4
  37. package/dist/features/column-sizing/columnSizingFeature.cjs.map +1 -1
  38. package/dist/features/column-sizing/columnSizingFeature.js +5 -5
  39. package/dist/features/column-sizing/columnSizingFeature.js.map +1 -1
  40. package/dist/features/column-sizing/columnSizingFeature.types.d.cts +18 -12
  41. package/dist/features/column-sizing/columnSizingFeature.types.d.ts +18 -12
  42. package/dist/features/column-sizing/columnSizingFeature.utils.cjs +24 -20
  43. package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
  44. package/dist/features/column-sizing/columnSizingFeature.utils.d.cts +18 -14
  45. package/dist/features/column-sizing/columnSizingFeature.utils.d.ts +18 -14
  46. package/dist/features/column-sizing/columnSizingFeature.utils.js +24 -20
  47. package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
  48. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +16 -16
  49. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
  50. package/dist/features/column-visibility/columnVisibilityFeature.utils.d.cts +3 -3
  51. package/dist/features/column-visibility/columnVisibilityFeature.utils.d.ts +3 -3
  52. package/dist/features/column-visibility/columnVisibilityFeature.utils.js +16 -16
  53. package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
  54. package/dist/static-functions.cjs +16 -16
  55. package/dist/static-functions.d.cts +3 -3
  56. package/dist/static-functions.d.ts +3 -3
  57. package/dist/static-functions.js +3 -3
  58. package/package.json +1 -1
  59. package/skills/api-not-found/SKILL.md +113 -0
  60. package/skills/client-vs-server/SKILL.md +164 -0
  61. package/skills/column-faceting/SKILL.md +91 -0
  62. package/skills/column-filtering/SKILL.md +82 -0
  63. package/skills/column-ordering/SKILL.md +75 -0
  64. package/skills/column-pinning/SKILL.md +89 -0
  65. package/skills/column-resizing/SKILL.md +91 -0
  66. package/skills/column-sizing/SKILL.md +72 -0
  67. package/skills/column-visibility/SKILL.md +75 -0
  68. package/skills/core/SKILL.md +140 -0
  69. package/skills/custom-features/SKILL.md +207 -0
  70. package/skills/expanding/SKILL.md +80 -0
  71. package/skills/global-filtering/SKILL.md +84 -0
  72. package/skills/grouping/SKILL.md +50 -394
  73. package/skills/migrate-v8-to-v9/SKILL.md +230 -390
  74. package/skills/pagination/SKILL.md +35 -344
  75. package/skills/row-pinning/SKILL.md +47 -238
  76. package/skills/row-selection/SKILL.md +39 -351
  77. package/skills/sorting/SKILL.md +35 -299
  78. package/skills/table-features/SKILL.md +153 -0
  79. package/skills/typescript/SKILL.md +126 -0
  80. package/src/core/headers/buildHeaderGroups.ts +1 -1
  81. package/src/core/headers/coreHeadersFeature.utils.ts +7 -7
  82. package/src/core/table/coreTablesFeature.utils.ts +1 -1
  83. package/src/features/column-ordering/columnOrderingFeature.types.ts +5 -5
  84. package/src/features/column-ordering/columnOrderingFeature.utils.ts +9 -9
  85. package/src/features/column-pinning/columnPinningFeature.ts +64 -59
  86. package/src/features/column-pinning/columnPinningFeature.types.ts +49 -38
  87. package/src/features/column-pinning/columnPinningFeature.utils.ts +163 -155
  88. package/src/features/column-sizing/columnSizingFeature.ts +6 -6
  89. package/src/features/column-sizing/columnSizingFeature.types.ts +18 -12
  90. package/src/features/column-sizing/columnSizingFeature.utils.ts +31 -27
  91. package/src/features/column-visibility/columnVisibilityFeature.utils.ts +15 -15
  92. package/skills/column-definitions/SKILL.md +0 -330
  93. package/skills/column-layout/SKILL.md +0 -326
  94. package/skills/column-layout/references/subsystems.md +0 -220
  95. package/skills/customizing-feature-behavior/SKILL.md +0 -423
  96. package/skills/filtering/SKILL.md +0 -375
  97. package/skills/filtering/references/faceting-and-fuzzy.md +0 -218
  98. package/skills/row-expanding/SKILL.md +0 -356
  99. package/skills/setup/SKILL.md +0 -390
  100. package/skills/state-management/SKILL.md +0 -403
@@ -1,403 +0,0 @@
1
- ---
2
- name: state-management
3
- description: >
4
- Coordinate TanStack Table v9 state across `initialState`, controlled
5
- `state`+`on*Change`, and external `atoms`. Covers the atom model
6
- (`table.atoms.<slice>`, `table.baseAtoms.<slice>`, `table.store`, `table.state`),
7
- per-slice precedence (atoms beat state beat initialState beat baseAtoms),
8
- `manualSorting` / `manualFiltering` / `manualPagination` / `manualGrouping` /
9
- `manualExpanding` for server-side data, `autoResetPageIndex` / `autoResetAll`,
10
- reset APIs (`resetSorting`, `resetPagination`, `reset()`), and the
11
- `SortingState` / `PaginationState` / `RowSelectionState` / `ColumnFiltersState` /
12
- `GroupingState` shapes. Foundational for every other skill.
13
- type: core
14
- library: tanstack-table
15
- library_version: '9.0.0-alpha.48'
16
- sources:
17
- - TanStack/table:docs/framework/vanilla/guide/table-state.md
18
- - TanStack/table:docs/framework/react/guide/table-state.md
19
- - TanStack/table:packages/table-core/src/store-reactivity-bindings.ts
20
- - TanStack/table:packages/table-core/src/reactivity.ts
21
- - TanStack/table:packages/table-core/src/core/table/constructTable.ts
22
- ---
23
-
24
- ## Setup
25
-
26
- TanStack Table v9 is built on TanStack Store. Each state slice (sorting, pagination, columnFilters, rowSelection, columnVisibility, …) is a separate atom. There are four ownership patterns, and the table reads from them in a fixed precedence.
27
-
28
- ```ts
29
- import {
30
- constructTable,
31
- tableFeatures,
32
- rowSortingFeature,
33
- rowPaginationFeature,
34
- createSortedRowModel,
35
- createPaginatedRowModel,
36
- sortFns,
37
- } from '@tanstack/table-core'
38
-
39
- const features = tableFeatures({
40
- rowSortingFeature,
41
- rowPaginationFeature,
42
- sortedRowModel: createSortedRowModel(),
43
- paginatedRowModel: createPaginatedRowModel(),
44
- sortFns,
45
- })
46
-
47
- const table = constructTable({
48
- features,
49
- columns,
50
- data,
51
- // 1. initialState — set starting values; read once at construction
52
- initialState: {
53
- sorting: [{ id: 'lastName', desc: false }],
54
- pagination: { pageIndex: 0, pageSize: 10 },
55
- },
56
- })
57
-
58
- // Read APIs:
59
- table.store.state // flat snapshot of every slice (no subscription)
60
- table.atoms.sorting.get() // single-slice atom read (no subscription)
61
- table.state // typed output of the `useTable` selector (framework adapters)
62
-
63
- // Write APIs use the feature setters — they're atom-aware:
64
- table.setSorting([{ id: 'firstName', desc: true }])
65
- table.setPageIndex(2)
66
- ```
67
-
68
- The four ownership patterns per slice:
69
-
70
- | Pattern | When to use | Wins over |
71
- | ----------------------------------- | ---------------------------------------------------- | ------------------------------- |
72
- | internal (default) | Most slices in a simple table | nothing — baseline |
73
- | `initialState.<slice>` | Set starting value only | internal default |
74
- | `state.<slice>` + `on<Slice>Change` | v8-style controlled state | `initialState` |
75
- | `atoms.<slice>` | v9 preferred — share with other components / queries | `state`+`on*Change` (silently!) |
76
-
77
- ## Core Patterns
78
-
79
- ### Internal state with `initialState`
80
-
81
- ```ts
82
- const table = constructTable({
83
- features,
84
- columns,
85
- data,
86
- initialState: { sorting: [{ id: 'age', desc: false }] },
87
- })
88
- // State lives entirely inside the table.
89
- table.setSorting([{ id: 'firstName', desc: true }])
90
- ```
91
-
92
- ### Controlled state with `state` + `on*Change` (v8-style)
93
-
94
- ```tsx
95
- const [sorting, setSorting] = React.useState<SortingState>([])
96
-
97
- const table = useTable({
98
- features,
99
- columns,
100
- data,
101
- state: { sorting },
102
- onSortingChange: setSorting,
103
- })
104
- ```
105
-
106
- `state` and `on*Change` must be paired. Without the callback the table cannot update React state, so toggling sort appears to do nothing.
107
-
108
- ### External atom (v9 preferred for shared slices)
109
-
110
- ```tsx
111
- import { useCreateAtom } from '@tanstack/react-store'
112
-
113
- function MyTable() {
114
- // Hoist or pass via context to share with queries / other components.
115
- const paginationAtom = useCreateAtom<PaginationState>({
116
- pageIndex: 0,
117
- pageSize: 10,
118
- })
119
-
120
- const table = useTable({
121
- features,
122
- columns,
123
- data,
124
- atoms: { pagination: paginationAtom },
125
- // no state.pagination, no onPaginationChange needed
126
- })
127
-
128
- return <Pager paginationAtom={paginationAtom} />
129
- }
130
- ```
131
-
132
- The atom IS the source of truth; `table.atoms.pagination` derives from it.
133
-
134
- ### Server-side / manual mode
135
-
136
- ```tsx
137
- const [pagination, setPagination] = React.useState({
138
- pageIndex: 0,
139
- pageSize: 10,
140
- })
141
- const dataQuery = useQuery({
142
- queryKey: ['rows', pagination],
143
- queryFn: () => fetchPage(pagination),
144
- })
145
-
146
- const table = useTable({
147
- features: tableFeatures({ rowPaginationFeature }),
148
- // no paginatedRowModel registered — server paginates
149
- columns,
150
- data: dataQuery.data?.rows ?? EMPTY,
151
- rowCount: dataQuery.data?.rowCount, // server tells the table the total
152
- state: { pagination },
153
- onPaginationChange: setPagination,
154
- manualPagination: true, // ← tell the table to NOT re-paginate
155
- })
156
- ```
157
-
158
- The same shape applies to `manualSorting`, `manualFiltering`, `manualGrouping`, `manualExpanding`. Without the flag, the table re-applies its client-side pipeline on top of already-prepared server data.
159
-
160
- ## Common Mistakes
161
-
162
- ### [CRITICAL] Passing both `state.<slice>` and `atoms.<slice>`
163
-
164
- Wrong:
165
-
166
- ```tsx
167
- // both ownership paths for the same slice
168
- const paginationAtom = useCreateAtom<PaginationState>({ pageIndex: 0, pageSize: 10 })
169
- const [pagination, setPagination] = React.useState(...)
170
-
171
- const table = useTable({
172
- features,
173
- columns,
174
- data,
175
- state: { pagination }, // ignored
176
- onPaginationChange: setPagination,
177
- atoms: { pagination: paginationAtom }, // wins
178
- })
179
- ```
180
-
181
- Correct:
182
-
183
- ```tsx
184
- // pick one ownership path per slice — here, external atoms
185
- const paginationAtom = useCreateAtom<PaginationState>({
186
- pageIndex: 0,
187
- pageSize: 10,
188
- })
189
-
190
- const table = useTable({
191
- features,
192
- columns,
193
- data,
194
- atoms: { pagination: paginationAtom },
195
- })
196
- ```
197
-
198
- When both are supplied, the external atom wins silently. `state.pagination` becomes dead config and `setPagination` writes never reach the table.
199
-
200
- Source: docs/framework/react/guide/table-state.md; packages/table-core/src/core/table/constructTable.ts
201
-
202
- ### [CRITICAL] Using external `state` without the matching `on*Change` callback
203
-
204
- Wrong:
205
-
206
- ```tsx
207
- const [sorting, setSorting] = React.useState<SortingState>([])
208
- const table = useTable({
209
- features,
210
- columns,
211
- data,
212
- state: { sorting }, // no onSortingChange
213
- })
214
- ```
215
-
216
- Correct:
217
-
218
- ```tsx
219
- const [sorting, setSorting] = React.useState<SortingState>([])
220
- const table = useTable({
221
- features,
222
- columns,
223
- data,
224
- state: { sorting },
225
- onSortingChange: setSorting,
226
- })
227
- ```
228
-
229
- The table keeps reading from `state.sorting`, so the UI looks stuck — sort toggles never make it back into React state.
230
-
231
- Source: docs/framework/react/guide/table-state.md; examples/react/basic-external-state/src/main.tsx
232
-
233
- ### [HIGH] Using `initialState` to control or update state
234
-
235
- Wrong:
236
-
237
- ```tsx
238
- // updates to initialState are ignored after first render
239
- function MyTable({ defaultSort }: { defaultSort: SortingState }) {
240
- const table = useTable({
241
- features,
242
- columns,
243
- data,
244
- initialState: { sorting: defaultSort }, // later changes never sync
245
- })
246
- }
247
- ```
248
-
249
- Correct:
250
-
251
- ```tsx
252
- function MyTable({ defaultSort }: { defaultSort: SortingState }) {
253
- const [sorting, setSorting] = React.useState(defaultSort)
254
- const table = useTable({
255
- features,
256
- columns,
257
- data,
258
- state: { sorting },
259
- onSortingChange: setSorting,
260
- })
261
- }
262
- ```
263
-
264
- `initialState` is read once at construction to seed `baseAtoms`. Mutating it later does nothing.
265
-
266
- Source: docs/framework/vanilla/guide/table-state.md; docs/framework/react/guide/table-state.md
267
-
268
- ### [HIGH] Writing to `table.baseAtoms.<slice>` while `atoms.<slice>` owns the slice
269
-
270
- Wrong:
271
-
272
- ```ts
273
- const paginationAtom = useCreateAtom<PaginationState>({
274
- pageIndex: 0,
275
- pageSize: 10,
276
- })
277
- const table = useTable({
278
- features,
279
- columns,
280
- data,
281
- atoms: { pagination: paginationAtom },
282
- })
283
-
284
- table.baseAtoms.pagination.set((old) => ({ ...old, pageIndex: 0 }))
285
- // baseAtom updated, but table.atoms.pagination still reads from paginationAtom
286
- ```
287
-
288
- Correct:
289
-
290
- ```ts
291
- // Write to the external atom directly, OR use the feature's setter API
292
- paginationAtom.set((old) => ({ ...old, pageIndex: 0 }))
293
- // or
294
- table.setPageIndex(0) // setter writes through the slice's updater (atom-aware)
295
- ```
296
-
297
- When an external atom owns a slice, `table.atoms.<slice>` derives from it — not from `baseAtoms`. Direct base-atom writes drift and never surface in the UI.
298
-
299
- Source: docs/framework/vanilla/guide/table-state.md; packages/table-core/src/core/table/constructTable.ts
300
-
301
- ### [CRITICAL] Forgetting `manualSorting` / `manualFiltering` / `manualPagination` for server-side data
302
-
303
- Wrong:
304
-
305
- ```tsx
306
- // data is already paginated server-side, but table still slices it
307
- const dataQuery = useQuery({
308
- queryKey: ['data', pagination],
309
- queryFn: fetchPage,
310
- })
311
- // features has paginatedRowModel registered
312
- const table = useTable({
313
- features,
314
- columns,
315
- data: dataQuery.data?.rows ?? [],
316
- rowCount: dataQuery.data?.rowCount,
317
- atoms: { pagination: paginationAtom },
318
- // ❌ missing manualPagination: true
319
- })
320
- ```
321
-
322
- Correct:
323
-
324
- ```tsx
325
- // Use features WITHOUT paginatedRowModel for fully server-side pagination
326
- const table = useTable({
327
- features: tableFeatures({ rowPaginationFeature }),
328
- columns,
329
- data: dataQuery.data?.rows ?? [],
330
- rowCount: dataQuery.data?.rowCount,
331
- atoms: { pagination: paginationAtom },
332
- manualPagination: true,
333
- })
334
- ```
335
-
336
- Without the manual flag, the table re-applies its client-side row models on top of already-prepared server data — wrong rows, broken page math, blank pages.
337
-
338
- Source: docs/framework/react/guide/table-state.md; packages/table-core/src/features/row-pagination/rowPaginationFeature.types.ts
339
-
340
- ### [HIGH] Using `table.reset()` to clear externally owned state
341
-
342
- Wrong:
343
-
344
- ```ts
345
- // external atom keeps its current value; only baseAtoms reset
346
- const sortingAtom = useCreateAtom<SortingState>([])
347
- const table = useTable({
348
- features,
349
- columns,
350
- data,
351
- atoms: { sorting: sortingAtom },
352
- })
353
- table.reset() // sortingAtom is NOT cleared
354
- ```
355
-
356
- Correct:
357
-
358
- ```ts
359
- // Use feature-specific reset — atom-aware
360
- table.resetSorting()
361
- // or, to clear the external atom specifically:
362
- sortingAtom.set([])
363
- ```
364
-
365
- `table.reset()` only resets `baseAtoms` to `initialState`; slices owned by external atoms or external `state` are untouched. The atom split makes `reset()` less safe than v8.
366
-
367
- Source: docs/framework/vanilla/guide/table-state.md; packages/table-core/src/core/table/coreTablesFeature.utils.ts
368
-
369
- ### [CRITICAL] Reimplementing what built-in setters provide
370
-
371
- Wrong:
372
-
373
- ```ts
374
- // Reimplements sorting state manually instead of using the API
375
- const [sorting, setSorting] = useState([])
376
- const sortedData = useMemo(() => [...data].sort(/* ... */), [data, sorting])
377
- // then uses sortedData directly, bypassing the table
378
- ```
379
-
380
- Correct:
381
-
382
- ```ts
383
- const table = useTable({
384
- features: tableFeatures({
385
- rowSortingFeature,
386
- sortedRowModel: createSortedRowModel(),
387
- sortFns,
388
- }),
389
- columns,
390
- data,
391
- })
392
- // table.setSorting(...), column.toggleSorting(), header.getToggleSortingHandler()
393
- ```
394
-
395
- The setters honor reset behavior, multi-sort, internal invariants. Hand-rolled state loops skip all of that.
396
-
397
- Source: maintainer interview (Phase 4, 2026-05-17)
398
-
399
- ## See also
400
-
401
- - `tanstack-table/setup` — how `features` (with row model factory and fn slots) is wired
402
- - `tanstack-table/pagination`, `tanstack-table/sorting`, `tanstack-table/filtering` — feature-specific `manual*` and reset semantics
403
- - `tanstack-table/migrate-v8-to-v9` — `table.getState()` → `table.store.state` / `table.atoms.<slice>.get()`