@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,356 +0,0 @@
1
- ---
2
- name: row-expanding
3
- description: >
4
- Expand and collapse rows in TanStack Table v9 with the `expandedRowModel`
5
- stage. Two patterns: (1) tree sub-rows via `getSubRows`, (2) detail panels
6
- via `getRowCanExpand`. Covers `rowExpandingFeature` + `createExpandedRowModel()`,
7
- `state.expanded` (ExpandedState = true | Record<string, boolean>),
8
- `onExpandedChange`, `manualExpanding`, `paginateExpandedRows` (default true),
9
- `autoResetExpanded`, `row.toggleExpanded` / `getIsExpanded` / `getCanExpand` /
10
- `getIsAllParentsExpanded` / `getToggleExpandedHandler`, `table.toggleAllRowsExpanded`,
11
- `row.depth` for indentation, and the `filterFromLeafRows` /
12
- `maxLeafRowFilterDepth` interaction with filtering.
13
- type: core
14
- library: tanstack-table
15
- library_version: '9.0.0-alpha.48'
16
- requires:
17
- - state-management
18
- sources:
19
- - TanStack/table:docs/guide/expanding.md
20
- - TanStack/table:packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
21
- - TanStack/table:examples/react/expanding/src/main.tsx
22
- - TanStack/table:examples/react/sub-components/src/main.tsx
23
- ---
24
-
25
- This skill builds on `tanstack-table/state-management`. Read it first for the atom model.
26
-
27
- ## Setup
28
-
29
- ```ts
30
- import {
31
- tableFeatures,
32
- rowExpandingFeature,
33
- createExpandedRowModel,
34
- constructTable,
35
- } from '@tanstack/table-core'
36
- import type { ExpandedState } from '@tanstack/table-core'
37
-
38
- const features = tableFeatures({
39
- rowExpandingFeature,
40
- expandedRowModel: createExpandedRowModel(),
41
- })
42
-
43
- // Tree mode — data has nested subRows
44
- const table = constructTable({
45
- features,
46
- columns,
47
- data,
48
- getSubRows: (row) => row.subRows,
49
- initialState: { expanded: {} satisfies ExpandedState },
50
- })
51
-
52
- // Or detail-panel mode — every row can expand to a sub-component
53
- const detailTable = constructTable({
54
- features,
55
- columns,
56
- data,
57
- getRowCanExpand: () => true,
58
- })
59
- ```
60
-
61
- ## Core Patterns
62
-
63
- ### Tree table with indentation
64
-
65
- ```tsx
66
- // From examples/react/expanding/src/main.tsx
67
- {
68
- row.getVisibleCells().map((cell, i) => (
69
- <td key={cell.id}>
70
- {i === 0 && row.getCanExpand() ? (
71
- <button
72
- onClick={row.getToggleExpandedHandler()}
73
- style={{ paddingLeft: `${row.depth * 2}rem` }}
74
- >
75
- {row.getIsExpanded() ? '👇' : '👉'}
76
- </button>
77
- ) : null}
78
- <table.FlexRender cell={cell} />
79
- </td>
80
- ))
81
- }
82
- ```
83
-
84
- `row.depth` is 0-based. `row.getCanExpand()` returns true when `row.subRows.length > 0`.
85
-
86
- ### Detail panels for flat data
87
-
88
- ```tsx
89
- // From examples/react/sub-components/src/main.tsx
90
- {
91
- table.getRowModel().rows.map((row) => (
92
- <React.Fragment key={row.id}>
93
- <tr>
94
- {row.getVisibleCells().map((cell) => (
95
- <td key={cell.id}>
96
- <table.FlexRender cell={cell} />
97
- </td>
98
- ))}
99
- </tr>
100
- {row.getIsExpanded() && (
101
- <tr>
102
- <td colSpan={row.getVisibleCells().length}>
103
- <SubComponent row={row} />
104
- </td>
105
- </tr>
106
- )}
107
- </React.Fragment>
108
- ))
109
- }
110
- ```
111
-
112
- ### Toggle ALL rows expanded at once
113
-
114
- ```tsx
115
- <button onClick={table.getToggleAllRowsExpandedHandler()}>
116
- {table.getIsAllRowsExpanded() ? '👇' : '👉'} Toggle All
117
- </button>
118
- ```
119
-
120
- ### Keep expanded children on their parent's page
121
-
122
- ```ts
123
- const table = constructTable({
124
- features: tableFeatures({
125
- rowExpandingFeature,
126
- rowPaginationFeature,
127
- expandedRowModel: createExpandedRowModel(),
128
- paginatedRowModel: createPaginatedRowModel(),
129
- }),
130
- columns,
131
- data,
132
- getSubRows: (r) => r.subRows,
133
- paginateExpandedRows: false, // children stay glued to their parent
134
- })
135
- ```
136
-
137
- `paginateExpandedRows: true` (default) flows expanded children through pagination — each child counts toward `pageSize`. `false` keeps them stuck under their parent.
138
-
139
- ### Tree filtering with leaf-match propagation
140
-
141
- ```ts
142
- const table = constructTable({
143
- features: tableFeatures({
144
- rowExpandingFeature,
145
- columnFilteringFeature,
146
- expandedRowModel: createExpandedRowModel(),
147
- filteredRowModel: createFilteredRowModel(),
148
- filterFns,
149
- }),
150
- columns,
151
- data,
152
- getSubRows: (r) => r.subRows,
153
- filterFromLeafRows: true, // keep parent visible when ANY descendant matches
154
- })
155
- ```
156
-
157
- ## Common Mistakes
158
-
159
- ### [HIGH] Setting `getRowCanExpand: () => true` together with tree data
160
-
161
- Wrong:
162
-
163
- ```ts
164
- // every row gets an expander icon, including leaves with no subRows
165
- const table = useTable({
166
- getRowCanExpand: () => true,
167
- getSubRows: (r) => r.subRows,
168
- })
169
- // In cell: row.getCanExpand() always true → leaf rows show 👉 with nothing to expand
170
- ```
171
-
172
- Correct:
173
-
174
- ```ts
175
- // For pure tree data, omit getRowCanExpand and let it auto-detect:
176
- const table = useTable({
177
- features,
178
- columns,
179
- data,
180
- getSubRows: (row) => row.subRows,
181
- // row.getCanExpand() is true only when subRows.length > 0
182
- })
183
-
184
- // For pure detail panels, override and skip getSubRows:
185
- const table = useTable({
186
- features: tableFeatures({
187
- rowExpandingFeature,
188
- expandedRowModel: createExpandedRowModel(),
189
- }),
190
- columns,
191
- data,
192
- getRowCanExpand: () => true,
193
- })
194
- ```
195
-
196
- `row_getCanExpand` resolves to `options.getRowCanExpand?.(row) ?? (enableExpanding ?? true) && !!row.subRows.length`. When `getRowCanExpand` is set, it wins — including for leaves.
197
-
198
- Source: packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
199
-
200
- ### [MEDIUM] Setting `paginateExpandedRows: false` and expecting `pageSize` to be a hard cap
201
-
202
- Wrong:
203
-
204
- ```ts
205
- const table = useTable({
206
- paginateExpandedRows: false,
207
- initialState: { pagination: { pageSize: 10 } },
208
- // user expands all parents → 10 parents * 5 children = 60 visible rows
209
- })
210
- ```
211
-
212
- Correct:
213
-
214
- ```ts
215
- // Default behavior — children flow through pagination, pageSize is enforced:
216
- const table = useTable({
217
- features,
218
- columns,
219
- data,
220
- getSubRows: (r) => r.subRows,
221
- // paginateExpandedRows defaults to true
222
- })
223
-
224
- // OR keep children with parent — accept that pageSize is a soft cap:
225
- // paginateExpandedRows: false
226
- ```
227
-
228
- `paginateExpandedRows: false` inflates each parent's page slice via `expandRows` — more rows render than `pageSize`. Pick deliberately.
229
-
230
- Source: packages/table-core/src/features/row-pagination/createPaginatedRowModel.ts
231
-
232
- ### [MEDIUM] Storing `expanded` as `true` then writing into it like a Record
233
-
234
- Wrong:
235
-
236
- ```ts
237
- // spreading `true` (a boolean) into an object gives {} - all rows collapse except [id]
238
- setExpanded((old) => ({ ...old, [row.id]: true }))
239
- // When old === true, this becomes { [row.id]: true } — everything else collapses!
240
- ```
241
-
242
- Correct:
243
-
244
- ```ts
245
- // Prefer the built-in handler — it materializes properly:
246
- <button onClick={row.getToggleExpandedHandler()}>
247
- {row.getIsExpanded() ? '👇' : '👉'}
248
- </button>
249
-
250
- // Or handle materialization yourself:
251
- table.setExpanded((old) => {
252
- if (old === true) {
253
- const map: Record<string, boolean> = {}
254
- Object.keys(table.getRowModel().rowsById).forEach((id) => { map[id] = true })
255
- return { ...map, [row.id]: !map[row.id] }
256
- }
257
- return { ...old, [row.id]: !(old as Record<string, boolean>)[row.id] }
258
- })
259
- ```
260
-
261
- `ExpandedState = true | Record<string, boolean>`. The `true` literal means "all rows expanded" — `row.toggleExpanded` materializes it correctly before applying per-row changes.
262
-
263
- Source: packages/table-core/src/features/row-expanding/rowExpandingFeature.utils.ts
264
-
265
- ### [MEDIUM] `manualExpanding: true` with `expandedRowModel` registered
266
-
267
- Wrong:
268
-
269
- ```ts
270
- // manualExpanding bypasses the expanded row model; sub-rows are never flattened
271
- const table = useTable({
272
- features: tableFeatures({
273
- rowExpandingFeature,
274
- expandedRowModel: createExpandedRowModel(), // ignored when manualExpanding: true
275
- }),
276
- columns,
277
- data,
278
- getSubRows: (r) => r.subRows,
279
- manualExpanding: true,
280
- })
281
- ```
282
-
283
- Correct:
284
-
285
- ```ts
286
- // Manual expanding is for server-side patterns where the server returns
287
- // a pre-flattened view based on which rows are expanded.
288
- const table = useTable({
289
- features: tableFeatures({ rowExpandingFeature }),
290
- // no expandedRowModel registered for manual mode
291
- columns,
292
- data: dataQuery.data, // server returns flattened rows when expanded
293
- manualExpanding: true,
294
- state: { expanded },
295
- onExpandedChange: setExpanded,
296
- })
297
-
298
- // For client-side tree, omit manualExpanding:
299
- const clientTable = useTable({
300
- features: tableFeatures({
301
- rowExpandingFeature,
302
- expandedRowModel: createExpandedRowModel(),
303
- }),
304
- columns,
305
- data,
306
- getSubRows: (r) => r.subRows,
307
- })
308
- ```
309
-
310
- With `manualExpanding: true`, `getExpandedRowModel` skips the registered factory and returns `getPreExpandedRowModel()` (sorted rows). The expanded state still tracks "which rows are open" but the row model is NOT inflated.
311
-
312
- Source: packages/table-core/src/core/row-models/coreRowModelsFeature.utils.ts
313
-
314
- ### [CRITICAL] Reimplementing tree flattening manually
315
-
316
- Wrong:
317
-
318
- ```ts
319
- // Hand-rolled tree-to-flat conversion
320
- const flatRows = useMemo(() => {
321
- const out: Person[] = []
322
- function walk(rows: Person[], depth = 0) {
323
- rows.forEach((r) => {
324
- out.push({ ...r, depth })
325
- if (expanded[r.id]) walk(r.subRows ?? [], depth + 1)
326
- })
327
- }
328
- walk(data)
329
- return out
330
- }, [data, expanded])
331
- ```
332
-
333
- Correct:
334
-
335
- ```ts
336
- const table = useTable({
337
- features: tableFeatures({
338
- rowExpandingFeature,
339
- expandedRowModel: createExpandedRowModel(),
340
- }),
341
- columns,
342
- data,
343
- getSubRows: (r) => r.subRows,
344
- })
345
-
346
- // then: table.getRowModel().rows already has row.depth and the expanded view
347
- table.getRowModel().rows.map((row) => /* render with row.depth */)
348
- ```
349
-
350
- Source: maintainer interview (Phase 4, 2026-05-17)
351
-
352
- ## See also
353
-
354
- - `tanstack-table/grouping` — pairs with expanding for drill-down on grouped rows
355
- - `tanstack-table/pagination` — `paginateExpandedRows` interaction
356
- - `tanstack-table/filtering` — `filterFromLeafRows` / `maxLeafRowFilterDepth` for tree filtering