@tanstack/table-core 9.0.0-alpha.47 → 9.0.0-alpha.48

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 (246) hide show
  1. package/README.md +10 -0
  2. package/dist/core/cells/coreCellsFeature.utils.cjs +11 -8
  3. package/dist/core/cells/coreCellsFeature.utils.cjs.map +1 -1
  4. package/dist/core/cells/coreCellsFeature.utils.d.cts +11 -8
  5. package/dist/core/cells/coreCellsFeature.utils.d.ts +11 -8
  6. package/dist/core/cells/coreCellsFeature.utils.js +11 -8
  7. package/dist/core/cells/coreCellsFeature.utils.js.map +1 -1
  8. package/dist/core/columns/coreColumnsFeature.types.d.cts +7 -6
  9. package/dist/core/columns/coreColumnsFeature.types.d.ts +7 -6
  10. package/dist/core/columns/coreColumnsFeature.utils.cjs +37 -27
  11. package/dist/core/columns/coreColumnsFeature.utils.cjs.map +1 -1
  12. package/dist/core/columns/coreColumnsFeature.utils.d.cts +37 -27
  13. package/dist/core/columns/coreColumnsFeature.utils.d.ts +37 -27
  14. package/dist/core/columns/coreColumnsFeature.utils.js +37 -27
  15. package/dist/core/columns/coreColumnsFeature.utils.js.map +1 -1
  16. package/dist/core/headers/coreHeadersFeature.types.d.cts +6 -4
  17. package/dist/core/headers/coreHeadersFeature.types.d.ts +6 -4
  18. package/dist/core/headers/coreHeadersFeature.utils.cjs +23 -18
  19. package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
  20. package/dist/core/headers/coreHeadersFeature.utils.d.cts +23 -18
  21. package/dist/core/headers/coreHeadersFeature.utils.d.ts +23 -18
  22. package/dist/core/headers/coreHeadersFeature.utils.js +23 -18
  23. package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
  24. package/dist/core/row-models/coreRowModelsFeature.utils.cjs +48 -36
  25. package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
  26. package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +48 -36
  27. package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +48 -36
  28. package/dist/core/row-models/coreRowModelsFeature.utils.js +48 -36
  29. package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
  30. package/dist/core/rows/coreRowsFeature.types.d.cts +4 -4
  31. package/dist/core/rows/coreRowsFeature.types.d.ts +4 -4
  32. package/dist/core/rows/coreRowsFeature.utils.cjs +34 -28
  33. package/dist/core/rows/coreRowsFeature.utils.cjs.map +1 -1
  34. package/dist/core/rows/coreRowsFeature.utils.d.cts +34 -28
  35. package/dist/core/rows/coreRowsFeature.utils.d.ts +34 -28
  36. package/dist/core/rows/coreRowsFeature.utils.js +34 -28
  37. package/dist/core/rows/coreRowsFeature.utils.js.map +1 -1
  38. package/dist/core/table/coreTablesFeature.types.d.cts +6 -2
  39. package/dist/core/table/coreTablesFeature.types.d.ts +6 -2
  40. package/dist/core/table/coreTablesFeature.utils.cjs +2 -2
  41. package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
  42. package/dist/core/table/coreTablesFeature.utils.d.cts +2 -2
  43. package/dist/core/table/coreTablesFeature.utils.d.ts +2 -2
  44. package/dist/core/table/coreTablesFeature.utils.js +2 -2
  45. package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
  46. package/dist/features/column-faceting/columnFacetingFeature.types.d.cts +16 -10
  47. package/dist/features/column-faceting/columnFacetingFeature.types.d.ts +16 -10
  48. package/dist/features/column-faceting/columnFacetingFeature.utils.cjs +26 -18
  49. package/dist/features/column-faceting/columnFacetingFeature.utils.cjs.map +1 -1
  50. package/dist/features/column-faceting/columnFacetingFeature.utils.d.cts +26 -18
  51. package/dist/features/column-faceting/columnFacetingFeature.utils.d.ts +26 -18
  52. package/dist/features/column-faceting/columnFacetingFeature.utils.js +26 -18
  53. package/dist/features/column-faceting/columnFacetingFeature.utils.js.map +1 -1
  54. package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +21 -11
  55. package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +21 -11
  56. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +39 -28
  57. package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
  58. package/dist/features/column-filtering/columnFilteringFeature.utils.d.cts +39 -28
  59. package/dist/features/column-filtering/columnFilteringFeature.utils.d.ts +39 -28
  60. package/dist/features/column-filtering/columnFilteringFeature.utils.js +39 -28
  61. package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
  62. package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +18 -14
  63. package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +18 -14
  64. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +55 -43
  65. package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
  66. package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +55 -43
  67. package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +55 -43
  68. package/dist/features/column-grouping/columnGroupingFeature.utils.js +55 -43
  69. package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
  70. package/dist/features/column-ordering/columnOrderingFeature.types.d.cts +14 -5
  71. package/dist/features/column-ordering/columnOrderingFeature.types.d.ts +14 -5
  72. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +30 -23
  73. package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
  74. package/dist/features/column-ordering/columnOrderingFeature.utils.d.cts +30 -23
  75. package/dist/features/column-ordering/columnOrderingFeature.utils.d.ts +30 -23
  76. package/dist/features/column-ordering/columnOrderingFeature.utils.js +30 -23
  77. package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
  78. package/dist/features/column-pinning/columnPinningFeature.types.d.cts +43 -31
  79. package/dist/features/column-pinning/columnPinningFeature.types.d.ts +43 -31
  80. package/dist/features/column-pinning/columnPinningFeature.utils.cjs +111 -91
  81. package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
  82. package/dist/features/column-pinning/columnPinningFeature.utils.d.cts +111 -91
  83. package/dist/features/column-pinning/columnPinningFeature.utils.d.ts +111 -91
  84. package/dist/features/column-pinning/columnPinningFeature.utils.js +111 -91
  85. package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
  86. package/dist/features/column-resizing/columnResizingFeature.types.d.cts +9 -9
  87. package/dist/features/column-resizing/columnResizingFeature.types.d.ts +9 -9
  88. package/dist/features/column-resizing/columnResizingFeature.utils.cjs +28 -19
  89. package/dist/features/column-resizing/columnResizingFeature.utils.cjs.map +1 -1
  90. package/dist/features/column-resizing/columnResizingFeature.utils.d.cts +28 -19
  91. package/dist/features/column-resizing/columnResizingFeature.utils.d.ts +28 -19
  92. package/dist/features/column-resizing/columnResizingFeature.utils.js +28 -19
  93. package/dist/features/column-resizing/columnResizingFeature.utils.js.map +1 -1
  94. package/dist/features/column-sizing/columnSizingFeature.types.d.cts +19 -12
  95. package/dist/features/column-sizing/columnSizingFeature.types.d.ts +19 -12
  96. package/dist/features/column-sizing/columnSizingFeature.utils.cjs +52 -41
  97. package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
  98. package/dist/features/column-sizing/columnSizingFeature.utils.d.cts +52 -41
  99. package/dist/features/column-sizing/columnSizingFeature.utils.d.ts +52 -41
  100. package/dist/features/column-sizing/columnSizingFeature.utils.js +52 -41
  101. package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
  102. package/dist/features/column-visibility/columnVisibilityFeature.types.d.cts +16 -13
  103. package/dist/features/column-visibility/columnVisibilityFeature.types.d.ts +16 -13
  104. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +54 -42
  105. package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
  106. package/dist/features/column-visibility/columnVisibilityFeature.utils.d.cts +54 -42
  107. package/dist/features/column-visibility/columnVisibilityFeature.utils.d.ts +54 -42
  108. package/dist/features/column-visibility/columnVisibilityFeature.utils.js +54 -42
  109. package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
  110. package/dist/features/global-filtering/globalFilteringFeature.types.d.cts +10 -5
  111. package/dist/features/global-filtering/globalFilteringFeature.types.d.ts +10 -5
  112. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +20 -14
  113. package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
  114. package/dist/features/global-filtering/globalFilteringFeature.utils.d.cts +20 -14
  115. package/dist/features/global-filtering/globalFilteringFeature.utils.d.ts +20 -14
  116. package/dist/features/global-filtering/globalFilteringFeature.utils.js +20 -14
  117. package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
  118. package/dist/features/row-expanding/rowExpandingFeature.types.d.cts +16 -15
  119. package/dist/features/row-expanding/rowExpandingFeature.types.d.ts +16 -15
  120. package/dist/features/row-expanding/rowExpandingFeature.utils.cjs +56 -41
  121. package/dist/features/row-expanding/rowExpandingFeature.utils.cjs.map +1 -1
  122. package/dist/features/row-expanding/rowExpandingFeature.utils.d.cts +56 -41
  123. package/dist/features/row-expanding/rowExpandingFeature.utils.d.ts +56 -41
  124. package/dist/features/row-expanding/rowExpandingFeature.utils.js +56 -41
  125. package/dist/features/row-expanding/rowExpandingFeature.utils.js.map +1 -1
  126. package/dist/features/row-pagination/rowPaginationFeature.types.d.cts +19 -12
  127. package/dist/features/row-pagination/rowPaginationFeature.types.d.ts +19 -12
  128. package/dist/features/row-pagination/rowPaginationFeature.utils.cjs +49 -32
  129. package/dist/features/row-pagination/rowPaginationFeature.utils.cjs.map +1 -1
  130. package/dist/features/row-pagination/rowPaginationFeature.utils.d.cts +49 -32
  131. package/dist/features/row-pagination/rowPaginationFeature.utils.d.ts +49 -32
  132. package/dist/features/row-pagination/rowPaginationFeature.utils.js +49 -32
  133. package/dist/features/row-pagination/rowPaginationFeature.utils.js.map +1 -1
  134. package/dist/features/row-pinning/rowPinningFeature.types.d.cts +12 -8
  135. package/dist/features/row-pinning/rowPinningFeature.types.d.ts +12 -8
  136. package/dist/features/row-pinning/rowPinningFeature.utils.cjs +39 -29
  137. package/dist/features/row-pinning/rowPinningFeature.utils.cjs.map +1 -1
  138. package/dist/features/row-pinning/rowPinningFeature.utils.d.cts +39 -29
  139. package/dist/features/row-pinning/rowPinningFeature.utils.d.ts +39 -29
  140. package/dist/features/row-pinning/rowPinningFeature.utils.js +39 -29
  141. package/dist/features/row-pinning/rowPinningFeature.utils.js.map +1 -1
  142. package/dist/features/row-selection/rowSelectionFeature.types.d.cts +30 -24
  143. package/dist/features/row-selection/rowSelectionFeature.types.d.ts +30 -24
  144. package/dist/features/row-selection/rowSelectionFeature.utils.cjs +89 -69
  145. package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
  146. package/dist/features/row-selection/rowSelectionFeature.utils.d.cts +89 -69
  147. package/dist/features/row-selection/rowSelectionFeature.utils.d.ts +89 -69
  148. package/dist/features/row-selection/rowSelectionFeature.utils.js +89 -69
  149. package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
  150. package/dist/features/row-sorting/rowSortingFeature.types.d.cts +10 -8
  151. package/dist/features/row-sorting/rowSortingFeature.types.d.ts +10 -8
  152. package/dist/features/row-sorting/rowSortingFeature.utils.cjs +61 -44
  153. package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
  154. package/dist/features/row-sorting/rowSortingFeature.utils.d.cts +61 -44
  155. package/dist/features/row-sorting/rowSortingFeature.utils.d.ts +61 -44
  156. package/dist/features/row-sorting/rowSortingFeature.utils.js +61 -44
  157. package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
  158. package/dist/fns/aggregationFns.cjs +33 -9
  159. package/dist/fns/aggregationFns.cjs.map +1 -1
  160. package/dist/fns/aggregationFns.d.cts +33 -9
  161. package/dist/fns/aggregationFns.d.ts +33 -9
  162. package/dist/fns/aggregationFns.js +33 -9
  163. package/dist/fns/aggregationFns.js.map +1 -1
  164. package/dist/fns/filterFns.cjs +48 -17
  165. package/dist/fns/filterFns.cjs.map +1 -1
  166. package/dist/fns/filterFns.d.cts +42 -15
  167. package/dist/fns/filterFns.d.ts +42 -15
  168. package/dist/fns/filterFns.js +48 -17
  169. package/dist/fns/filterFns.js.map +1 -1
  170. package/dist/helpers/columnHelper.cjs +9 -4
  171. package/dist/helpers/columnHelper.cjs.map +1 -1
  172. package/dist/helpers/columnHelper.d.cts +9 -4
  173. package/dist/helpers/columnHelper.d.ts +9 -4
  174. package/dist/helpers/columnHelper.js +9 -4
  175. package/dist/helpers/columnHelper.js.map +1 -1
  176. package/dist/helpers/tableOptions.cjs.map +1 -1
  177. package/dist/helpers/tableOptions.d.cts +12 -9
  178. package/dist/helpers/tableOptions.d.ts +12 -9
  179. package/dist/helpers/tableOptions.js.map +1 -1
  180. package/dist/types/ColumnDef.d.cts +38 -0
  181. package/dist/types/ColumnDef.d.ts +38 -0
  182. package/dist/types/TableOptions.d.cts +15 -0
  183. package/dist/types/TableOptions.d.ts +15 -0
  184. package/dist/types/TableState.d.cts +12 -0
  185. package/dist/types/TableState.d.ts +12 -0
  186. package/package.json +5 -3
  187. package/skills/column-definitions/SKILL.md +333 -0
  188. package/skills/column-layout/SKILL.md +328 -0
  189. package/skills/column-layout/references/subsystems.md +220 -0
  190. package/skills/customizing-feature-behavior/SKILL.md +416 -0
  191. package/skills/filtering/SKILL.md +357 -0
  192. package/skills/filtering/references/faceting-and-fuzzy.md +191 -0
  193. package/skills/grouping/SKILL.md +448 -0
  194. package/skills/migrate-v8-to-v9/SKILL.md +495 -0
  195. package/skills/pagination/SKILL.md +385 -0
  196. package/skills/row-expanding/SKILL.md +348 -0
  197. package/skills/row-pinning/SKILL.md +269 -0
  198. package/skills/row-selection/SKILL.md +391 -0
  199. package/skills/setup/SKILL.md +400 -0
  200. package/skills/sorting/SKILL.md +344 -0
  201. package/skills/state-management/SKILL.md +388 -0
  202. package/src/core/cells/coreCellsFeature.utils.ts +11 -8
  203. package/src/core/columns/coreColumnsFeature.types.ts +7 -6
  204. package/src/core/columns/coreColumnsFeature.utils.ts +37 -27
  205. package/src/core/headers/coreHeadersFeature.types.ts +6 -4
  206. package/src/core/headers/coreHeadersFeature.utils.ts +23 -18
  207. package/src/core/row-models/coreRowModelsFeature.utils.ts +48 -36
  208. package/src/core/rows/coreRowsFeature.types.ts +4 -4
  209. package/src/core/rows/coreRowsFeature.utils.ts +34 -28
  210. package/src/core/table/coreTablesFeature.types.ts +6 -2
  211. package/src/core/table/coreTablesFeature.utils.ts +2 -2
  212. package/src/features/column-faceting/columnFacetingFeature.types.ts +16 -10
  213. package/src/features/column-faceting/columnFacetingFeature.utils.ts +26 -18
  214. package/src/features/column-filtering/columnFilteringFeature.types.ts +21 -11
  215. package/src/features/column-filtering/columnFilteringFeature.utils.ts +39 -28
  216. package/src/features/column-grouping/columnGroupingFeature.types.ts +18 -14
  217. package/src/features/column-grouping/columnGroupingFeature.utils.ts +55 -43
  218. package/src/features/column-ordering/columnOrderingFeature.types.ts +14 -5
  219. package/src/features/column-ordering/columnOrderingFeature.utils.ts +30 -23
  220. package/src/features/column-pinning/columnPinningFeature.types.ts +43 -31
  221. package/src/features/column-pinning/columnPinningFeature.utils.ts +111 -91
  222. package/src/features/column-resizing/columnResizingFeature.types.ts +9 -9
  223. package/src/features/column-resizing/columnResizingFeature.utils.ts +28 -19
  224. package/src/features/column-sizing/columnSizingFeature.types.ts +19 -12
  225. package/src/features/column-sizing/columnSizingFeature.utils.ts +52 -41
  226. package/src/features/column-visibility/columnVisibilityFeature.types.ts +16 -13
  227. package/src/features/column-visibility/columnVisibilityFeature.utils.ts +54 -42
  228. package/src/features/global-filtering/globalFilteringFeature.types.ts +10 -5
  229. package/src/features/global-filtering/globalFilteringFeature.utils.ts +20 -14
  230. package/src/features/row-expanding/rowExpandingFeature.types.ts +16 -15
  231. package/src/features/row-expanding/rowExpandingFeature.utils.ts +56 -41
  232. package/src/features/row-pagination/rowPaginationFeature.types.ts +19 -12
  233. package/src/features/row-pagination/rowPaginationFeature.utils.ts +49 -32
  234. package/src/features/row-pinning/rowPinningFeature.types.ts +12 -8
  235. package/src/features/row-pinning/rowPinningFeature.utils.ts +39 -29
  236. package/src/features/row-selection/rowSelectionFeature.types.ts +30 -24
  237. package/src/features/row-selection/rowSelectionFeature.utils.ts +89 -69
  238. package/src/features/row-sorting/rowSortingFeature.types.ts +10 -8
  239. package/src/features/row-sorting/rowSortingFeature.utils.ts +61 -44
  240. package/src/fns/aggregationFns.ts +33 -9
  241. package/src/fns/filterFns.ts +48 -17
  242. package/src/helpers/columnHelper.ts +9 -4
  243. package/src/helpers/tableOptions.ts +12 -9
  244. package/src/types/ColumnDef.ts +38 -0
  245. package/src/types/TableOptions.ts +15 -0
  246. package/src/types/TableState.ts +12 -0
@@ -0,0 +1,391 @@
1
+ ---
2
+ name: row-selection
3
+ description: >
4
+ Track which rows are selected in TanStack Table v9 via
5
+ `rowSelection: Record<rowId, boolean | undefined>`. Covers `rowSelectionFeature`,
6
+ the three selected-row APIs (`getSelectedRowModel`, `getFilteredSelectedRowModel`,
7
+ `getGroupedSelectedRowModel`), `row.toggleSelected` / `getIsSelected` /
8
+ `getIsSomeSelected` (indeterminate) / `getCanSelect` / `getCanMultiSelect`,
9
+ `row.getToggleSelectedHandler`, header APIs (`getIsAllRowsSelected` /
10
+ `getIsSomeRowsSelected` / `getToggleAllRowsSelectedHandler` and the page-aware
11
+ variants), `enableRowSelection` (bool or predicate),
12
+ `enableMultiRowSelection: false` for radio-style, `enableSubRowSelection`,
13
+ and why `getRowId` is essentially mandatory — especially under server pagination.
14
+ type: core
15
+ library: tanstack-table
16
+ library_version: '9.0.0-alpha.47'
17
+ requires:
18
+ - state-management
19
+ - column-definitions
20
+ sources:
21
+ - TanStack/table:docs/guide/row-selection.md
22
+ - TanStack/table:packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts
23
+ - TanStack/table:packages/table-core/src/features/row-selection/rowSelectionFeature.types.ts
24
+ - TanStack/table:examples/react/row-selection/src/main.tsx
25
+ ---
26
+
27
+ This skill builds on `tanstack-table/state-management` and `tanstack-table/column-definitions`. Read those first for state ownership and `getRowId`.
28
+
29
+ ## Setup
30
+
31
+ ```ts
32
+ import {
33
+ tableFeatures,
34
+ rowSelectionFeature,
35
+ constructTable,
36
+ } from '@tanstack/table-core'
37
+ import type { RowSelectionState } from '@tanstack/table-core'
38
+
39
+ const _features = tableFeatures({ rowSelectionFeature })
40
+
41
+ const table = constructTable({
42
+ _features,
43
+ _rowModels: {},
44
+ columns,
45
+ data,
46
+ getRowId: (row) => row.id, // ← essentially mandatory
47
+ initialState: { rowSelection: {} satisfies RowSelectionState },
48
+ enableRowSelection: true,
49
+ })
50
+ ```
51
+
52
+ ## Core Patterns
53
+
54
+ ### Select column with header "select all" + per-row checkbox
55
+
56
+ ```tsx
57
+ // From examples/react/row-selection/src/main.tsx
58
+ columnHelper.display({
59
+ id: 'select',
60
+ header: ({ table }) => (
61
+ <Checkbox
62
+ checked={table.getIsAllRowsSelected()}
63
+ indeterminate={table.getIsSomeRowsSelected()}
64
+ onChange={table.getToggleAllRowsSelectedHandler()}
65
+ />
66
+ ),
67
+ cell: ({ row }) => (
68
+ <Checkbox
69
+ checked={row.getIsSelected()}
70
+ indeterminate={row.getIsSomeSelected()}
71
+ disabled={!row.getCanSelect()}
72
+ onChange={row.getToggleSelectedHandler()}
73
+ />
74
+ ),
75
+ }),
76
+ ```
77
+
78
+ ### Single-select (radio-style)
79
+
80
+ ```tsx
81
+ const table = useTable({
82
+ _features: tableFeatures({ rowSelectionFeature }),
83
+ _rowModels: {},
84
+ columns,
85
+ data,
86
+ getRowId: (row) => row.id,
87
+ enableMultiRowSelection: false, // ← radio-like
88
+ })
89
+
90
+ // Cell renders a radio, no "select all" header makes sense
91
+ columnHelper.display({
92
+ id: 'select',
93
+ header: '', // no select-all in single-select mode
94
+ cell: ({ row }) => (
95
+ <input
96
+ type="radio"
97
+ name="row-selection"
98
+ checked={row.getIsSelected()}
99
+ disabled={!row.getCanSelect()}
100
+ onChange={row.getToggleSelectedHandler()}
101
+ />
102
+ ),
103
+ })
104
+ ```
105
+
106
+ ### Conditional selection per row
107
+
108
+ ```ts
109
+ const table = useTable({
110
+ _features,
111
+ columns,
112
+ data,
113
+ getRowId: (row) => row.id,
114
+ enableRowSelection: (row) => row.original.age > 18, // predicate form
115
+ })
116
+ ```
117
+
118
+ ### Three selected-row APIs
119
+
120
+ ```ts
121
+ table.getSelectedRowModel() // built off core — raw data
122
+ table.getFilteredSelectedRowModel() // built off filtered — current filters applied
123
+ table.getGroupedSelectedRowModel() // built off grouped — current groups applied
124
+ ```
125
+
126
+ ### Hoist selection to an external atom
127
+
128
+ ```tsx
129
+ import { useCreateAtom } from '@tanstack/react-store'
130
+
131
+ const rowSelectionAtom = useCreateAtom<RowSelectionState>({})
132
+
133
+ const table = useTable({
134
+ _features,
135
+ columns,
136
+ data,
137
+ getRowId: (row) => row.id,
138
+ atoms: { rowSelection: rowSelectionAtom },
139
+ })
140
+
141
+ // Send selected IDs to an API call from a sibling component
142
+ function ExportButton() {
143
+ const selection = useStore(rowSelectionAtom)
144
+ return (
145
+ <button onClick={() => api.export(Object.keys(selection))}>Export</button>
146
+ )
147
+ }
148
+ ```
149
+
150
+ ## Common Mistakes
151
+
152
+ ### [HIGH] Omitting `getRowId` under `manualPagination`
153
+
154
+ Wrong:
155
+
156
+ ```ts
157
+ // Server-side pagination + default row.id = row.index
158
+ const table = useTable({
159
+ _features: tableFeatures({ rowSelectionFeature, rowPaginationFeature }),
160
+ data, // only current page from server
161
+ manualPagination: true,
162
+ rowCount,
163
+ })
164
+ // After paging, rowSelection: { '5': true } is ambiguous
165
+ // — selection appears to move with the user.
166
+ ```
167
+
168
+ Correct:
169
+
170
+ ```ts
171
+ const table = useTable({
172
+ _features: tableFeatures({ rowSelectionFeature, rowPaginationFeature }),
173
+ data,
174
+ manualPagination: true,
175
+ rowCount,
176
+ getRowId: (row) => row.uuid, // stable across pages
177
+ })
178
+
179
+ // For "X of Y selected" with server-side pagination, read state directly:
180
+ const totalSelected = Object.keys(table.state.rowSelection).length
181
+ ```
182
+
183
+ `row.id` defaults to `row.index`. Under `manualPagination`, every page reuses indices 0..n-1, so selection IDs collide across pages.
184
+
185
+ Source: docs/guide/row-selection.md; examples/react/row-selection/src/main.tsx
186
+
187
+ ### [MEDIUM] `enableMultiRowSelection: false` + a "select all" checkbox header
188
+
189
+ Wrong:
190
+
191
+ ```tsx
192
+ const table = useTable({
193
+ _features: tableFeatures({ rowSelectionFeature }),
194
+ enableMultiRowSelection: false, // radio-like
195
+ })
196
+
197
+ // Header still renders a checkbox + indeterminate
198
+ <Checkbox
199
+ checked={table.getIsAllRowsSelected()}
200
+ indeterminate={table.getIsSomeRowsSelected()}
201
+ onChange={table.getToggleAllRowsSelectedHandler()}
202
+ />
203
+ ```
204
+
205
+ Correct:
206
+
207
+ ```tsx
208
+ const table = useTable({
209
+ _features: tableFeatures({ rowSelectionFeature }),
210
+ enableMultiRowSelection: false,
211
+ getRowId: (row) => row.id,
212
+ })
213
+
214
+ // Drop the toggle-all header in single-select mode
215
+ columnHelper.display({
216
+ id: 'select',
217
+ header: '',
218
+ cell: ({ row }) => (
219
+ <input
220
+ type="radio"
221
+ name="row-selection"
222
+ checked={row.getIsSelected()}
223
+ disabled={!row.getCanSelect()}
224
+ onChange={row.getToggleSelectedHandler()}
225
+ />
226
+ ),
227
+ })
228
+ ```
229
+
230
+ In single-select mode, `mutateRowIsSelected` clears all other ids before adding the new one. "Select all" becomes effectively no-op and indeterminate is meaningless.
231
+
232
+ Source: docs/guide/row-selection.md; packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts
233
+
234
+ ### [HIGH] `getSelectedRowModel().flatRows` for counts under `manualPagination`
235
+
236
+ Wrong:
237
+
238
+ ```ts
239
+ // Under manualPagination, only counts the visible page's selected rows
240
+ const selectedCount = table.getSelectedRowModel().flatRows.length
241
+
242
+ const handleBulkAction = () => {
243
+ const ids = table.getSelectedRowModel().flatRows.map((row) => row.original.id)
244
+ api.archive(ids) // missing all selections from other pages!
245
+ }
246
+ ```
247
+
248
+ Correct:
249
+
250
+ ```ts
251
+ // For counts and id lists under manualPagination, read state directly
252
+ const selectedCount = Object.keys(table.state.rowSelection).length
253
+
254
+ const handleBulkAction = () => {
255
+ const ids = Object.keys(table.state.rowSelection)
256
+ api.archive(ids)
257
+ }
258
+ // (Client-side: getSelectedRowModel is fine — data contains every row.)
259
+ ```
260
+
261
+ `getSelectedRowModel` walks the core row model — which under `manualPagination` only contains the current page. `state.rowSelection` may contain ids that aren't in `data` (that's by design).
262
+
263
+ Source: docs/guide/row-selection.md; packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts
264
+
265
+ ### [MEDIUM] Surprise sub-row propagation from `enableSubRowSelection` default
266
+
267
+ Wrong:
268
+
269
+ ```ts
270
+ // Default behavior: clicking the parent selects all children
271
+ const table = useTable({
272
+ _features: tableFeatures({ rowSelectionFeature, rowExpandingFeature }),
273
+ getSubRows: (row) => row.subRows,
274
+ // enableSubRowSelection unset — defaults to true
275
+ })
276
+ ```
277
+
278
+ Correct:
279
+
280
+ ```ts
281
+ const table = useTable({
282
+ _features: tableFeatures({ rowSelectionFeature, rowExpandingFeature }),
283
+ getSubRows: (row) => row.subRows,
284
+ enableSubRowSelection: false, // toggling parent doesn't touch subRows
285
+ })
286
+
287
+ // Or selectively:
288
+ enableSubRowSelection: (row) => row.depth > 0,
289
+
290
+ // Indeterminate parent checkbox
291
+ <Checkbox
292
+ checked={row.getIsSelected()}
293
+ indeterminate={row.getIsSomeSelected()} // 'some' descendants selected
294
+ disabled={!row.getCanSelect()}
295
+ onChange={row.getToggleSelectedHandler()}
296
+ />
297
+ ```
298
+
299
+ `enableSubRowSelection: true` is the default. `mutateRowIsSelected` recurses into `row.subRows` when truthy. Decide deliberately — "select group as a whole" UX wants this off.
300
+
301
+ Source: docs/guide/row-selection.md; packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts
302
+
303
+ ### [HIGH] Parent checkbox stuck "unchecked" with all sub-rows selected (deep trees)
304
+
305
+ Wrong:
306
+
307
+ ```ts
308
+ // Returns false even when all leaf descendants are selected
309
+ const isParentChecked = row.getIsAllSubRowsSelected()
310
+ ```
311
+
312
+ Correct:
313
+
314
+ ```ts
315
+ const allLeafs = row.getLeafRows()
316
+ const allSelected =
317
+ allLeafs.length > 0 && allLeafs.every((r) => r.getIsSelected())
318
+ const someSelected = allLeafs.some((r) => r.getIsSelected())
319
+ ```
320
+
321
+ `getIsAllSubRowsSelected` only counts direct children. With multi-level grouping, a parent reports based on a partial count.
322
+
323
+ Source: https://github.com/TanStack/table/issues/4878; https://github.com/TanStack/table/issues/4759
324
+
325
+ ### [HIGH] Stale rowSelection IDs after data refresh
326
+
327
+ Wrong:
328
+
329
+ ```ts
330
+ useEffect(() => {
331
+ refreshData() // selection still references deleted IDs
332
+ }, [trigger])
333
+ ```
334
+
335
+ Correct:
336
+
337
+ ```ts
338
+ useEffect(() => {
339
+ setRowSelection((prev) => {
340
+ const validIds = new Set(data.map((row) => row.id))
341
+ const next: RowSelectionState = {}
342
+ for (const id in prev) if (validIds.has(id)) next[id] = prev[id]
343
+ return next
344
+ })
345
+ }, [data])
346
+ ```
347
+
348
+ v8 removed v7's `autoResetSelectedRows`. With websockets / refetch, IDs that no longer exist remain in `rowSelection` and `getIsAllRowsSelected()` returns true based on stale state. Prune yourself.
349
+
350
+ Source: https://github.com/TanStack/table/issues/5850; https://github.com/TanStack/table/issues/4498
351
+
352
+ ### [CRITICAL] Reimplementing selection state manually
353
+
354
+ Wrong:
355
+
356
+ ```ts
357
+ // Hand-rolled "selected" set, bypassing the table
358
+ const [selected, setSelected] = useState(new Set<string>())
359
+ const toggle = (id: string) => {
360
+ setSelected((s) => {
361
+ const next = new Set(s)
362
+ next.has(id) ? next.delete(id) : next.add(id)
363
+ return next
364
+ })
365
+ }
366
+ ```
367
+
368
+ Correct:
369
+
370
+ ```ts
371
+ const table = useTable({
372
+ _features: tableFeatures({ rowSelectionFeature }),
373
+ _rowModels: {},
374
+ columns,
375
+ data,
376
+ getRowId: (row) => row.id,
377
+ })
378
+ row.toggleSelected()
379
+ row.toggleSelected(true)
380
+ table.toggleAllRowsSelected()
381
+ table.setRowSelection({ abc: true })
382
+ ```
383
+
384
+ Source: maintainer interview (Phase 4, 2026-05-17)
385
+
386
+ ## See also
387
+
388
+ - `tanstack-table/column-definitions` — `getRowId` is the foundation of every row-keyed feature
389
+ - `tanstack-table/state-management` — `rowSelection` slice + atoms for sharing selection
390
+ - `tanstack-table/pagination` — server-pagination "select all" pitfalls
391
+ - `tanstack-table/grouping` — `getGroupedSelectedRowModel` distinction