@tanstack/table-core 9.0.0-alpha.47 → 9.0.0-alpha.49
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.
- package/README.md +10 -0
- package/dist/core/cells/coreCellsFeature.utils.cjs +11 -8
- package/dist/core/cells/coreCellsFeature.utils.cjs.map +1 -1
- package/dist/core/cells/coreCellsFeature.utils.d.cts +11 -8
- package/dist/core/cells/coreCellsFeature.utils.d.ts +11 -8
- package/dist/core/cells/coreCellsFeature.utils.js +11 -8
- package/dist/core/cells/coreCellsFeature.utils.js.map +1 -1
- package/dist/core/columns/coreColumnsFeature.types.d.cts +7 -6
- package/dist/core/columns/coreColumnsFeature.types.d.ts +7 -6
- package/dist/core/columns/coreColumnsFeature.utils.cjs +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.cjs.map +1 -1
- package/dist/core/columns/coreColumnsFeature.utils.d.cts +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.d.ts +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.js +37 -27
- package/dist/core/columns/coreColumnsFeature.utils.js.map +1 -1
- package/dist/core/headers/coreHeadersFeature.types.d.cts +6 -4
- package/dist/core/headers/coreHeadersFeature.types.d.ts +6 -4
- package/dist/core/headers/coreHeadersFeature.utils.cjs +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.cjs.map +1 -1
- package/dist/core/headers/coreHeadersFeature.utils.d.cts +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.d.ts +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.js +23 -18
- package/dist/core/headers/coreHeadersFeature.utils.js.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.cjs.map +1 -1
- package/dist/core/row-models/coreRowModelsFeature.utils.d.cts +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.d.ts +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.js +48 -36
- package/dist/core/row-models/coreRowModelsFeature.utils.js.map +1 -1
- package/dist/core/rows/coreRowsFeature.types.d.cts +4 -4
- package/dist/core/rows/coreRowsFeature.types.d.ts +4 -4
- package/dist/core/rows/coreRowsFeature.utils.cjs +34 -28
- package/dist/core/rows/coreRowsFeature.utils.cjs.map +1 -1
- package/dist/core/rows/coreRowsFeature.utils.d.cts +34 -28
- package/dist/core/rows/coreRowsFeature.utils.d.ts +34 -28
- package/dist/core/rows/coreRowsFeature.utils.js +34 -28
- package/dist/core/rows/coreRowsFeature.utils.js.map +1 -1
- package/dist/core/table/coreTablesFeature.types.d.cts +6 -2
- package/dist/core/table/coreTablesFeature.types.d.ts +6 -2
- package/dist/core/table/coreTablesFeature.utils.cjs +2 -2
- package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.d.cts +2 -2
- package/dist/core/table/coreTablesFeature.utils.d.ts +2 -2
- package/dist/core/table/coreTablesFeature.utils.js +2 -2
- package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
- package/dist/features/column-faceting/columnFacetingFeature.types.d.cts +16 -10
- package/dist/features/column-faceting/columnFacetingFeature.types.d.ts +16 -10
- package/dist/features/column-faceting/columnFacetingFeature.utils.cjs +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.cjs.map +1 -1
- package/dist/features/column-faceting/columnFacetingFeature.utils.d.cts +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.d.ts +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.js +26 -18
- package/dist/features/column-faceting/columnFacetingFeature.utils.js.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.types.d.cts +21 -11
- package/dist/features/column-filtering/columnFilteringFeature.types.d.ts +21 -11
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.cts +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.d.ts +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.js +39 -28
- package/dist/features/column-filtering/columnFilteringFeature.utils.js.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.types.d.cts +18 -14
- package/dist/features/column-grouping/columnGroupingFeature.types.d.ts +18 -14
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.cjs.map +1 -1
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.cts +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.d.ts +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.js +55 -43
- package/dist/features/column-grouping/columnGroupingFeature.utils.js.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.types.d.cts +14 -5
- package/dist/features/column-ordering/columnOrderingFeature.types.d.ts +14 -5
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.cjs.map +1 -1
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.cts +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.d.ts +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.js +30 -23
- package/dist/features/column-ordering/columnOrderingFeature.utils.js.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.types.d.cts +43 -31
- package/dist/features/column-pinning/columnPinningFeature.types.d.ts +43 -31
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.cjs.map +1 -1
- package/dist/features/column-pinning/columnPinningFeature.utils.d.cts +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.d.ts +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.js +111 -91
- package/dist/features/column-pinning/columnPinningFeature.utils.js.map +1 -1
- package/dist/features/column-resizing/columnResizingFeature.types.d.cts +9 -9
- package/dist/features/column-resizing/columnResizingFeature.types.d.ts +9 -9
- package/dist/features/column-resizing/columnResizingFeature.utils.cjs +29 -20
- package/dist/features/column-resizing/columnResizingFeature.utils.cjs.map +1 -1
- package/dist/features/column-resizing/columnResizingFeature.utils.d.cts +28 -19
- package/dist/features/column-resizing/columnResizingFeature.utils.d.ts +28 -19
- package/dist/features/column-resizing/columnResizingFeature.utils.js +29 -20
- package/dist/features/column-resizing/columnResizingFeature.utils.js.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.types.d.cts +19 -12
- package/dist/features/column-sizing/columnSizingFeature.types.d.ts +19 -12
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.cjs.map +1 -1
- package/dist/features/column-sizing/columnSizingFeature.utils.d.cts +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.d.ts +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.js +52 -41
- package/dist/features/column-sizing/columnSizingFeature.utils.js.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.types.d.cts +16 -13
- package/dist/features/column-visibility/columnVisibilityFeature.types.d.ts +16 -13
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.cjs.map +1 -1
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.cts +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.d.ts +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js +54 -42
- package/dist/features/column-visibility/columnVisibilityFeature.utils.js.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.types.d.cts +10 -5
- package/dist/features/global-filtering/globalFilteringFeature.types.d.ts +10 -5
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.cjs.map +1 -1
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.cts +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.d.ts +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.js +20 -14
- package/dist/features/global-filtering/globalFilteringFeature.utils.js.map +1 -1
- package/dist/features/row-expanding/rowExpandingFeature.types.d.cts +16 -15
- package/dist/features/row-expanding/rowExpandingFeature.types.d.ts +16 -15
- package/dist/features/row-expanding/rowExpandingFeature.utils.cjs +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.cjs.map +1 -1
- package/dist/features/row-expanding/rowExpandingFeature.utils.d.cts +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.d.ts +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.js +56 -41
- package/dist/features/row-expanding/rowExpandingFeature.utils.js.map +1 -1
- package/dist/features/row-pagination/rowPaginationFeature.types.d.cts +19 -12
- package/dist/features/row-pagination/rowPaginationFeature.types.d.ts +19 -12
- package/dist/features/row-pagination/rowPaginationFeature.utils.cjs +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.cjs.map +1 -1
- package/dist/features/row-pagination/rowPaginationFeature.utils.d.cts +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.d.ts +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.js +49 -32
- package/dist/features/row-pagination/rowPaginationFeature.utils.js.map +1 -1
- package/dist/features/row-pinning/rowPinningFeature.types.d.cts +12 -8
- package/dist/features/row-pinning/rowPinningFeature.types.d.ts +12 -8
- package/dist/features/row-pinning/rowPinningFeature.utils.cjs +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.cjs.map +1 -1
- package/dist/features/row-pinning/rowPinningFeature.utils.d.cts +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.d.ts +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.js +39 -29
- package/dist/features/row-pinning/rowPinningFeature.utils.js.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.types.d.cts +30 -24
- package/dist/features/row-selection/rowSelectionFeature.types.d.ts +30 -24
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.utils.d.cts +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.d.ts +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.js +89 -69
- package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.types.d.cts +10 -8
- package/dist/features/row-sorting/rowSortingFeature.types.d.ts +10 -8
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs +62 -45
- package/dist/features/row-sorting/rowSortingFeature.utils.cjs.map +1 -1
- package/dist/features/row-sorting/rowSortingFeature.utils.d.cts +61 -44
- package/dist/features/row-sorting/rowSortingFeature.utils.d.ts +61 -44
- package/dist/features/row-sorting/rowSortingFeature.utils.js +62 -45
- package/dist/features/row-sorting/rowSortingFeature.utils.js.map +1 -1
- package/dist/fns/aggregationFns.cjs +33 -9
- package/dist/fns/aggregationFns.cjs.map +1 -1
- package/dist/fns/aggregationFns.d.cts +33 -9
- package/dist/fns/aggregationFns.d.ts +33 -9
- package/dist/fns/aggregationFns.js +33 -9
- package/dist/fns/aggregationFns.js.map +1 -1
- package/dist/fns/filterFns.cjs +48 -17
- package/dist/fns/filterFns.cjs.map +1 -1
- package/dist/fns/filterFns.d.cts +42 -15
- package/dist/fns/filterFns.d.ts +42 -15
- package/dist/fns/filterFns.js +48 -17
- package/dist/fns/filterFns.js.map +1 -1
- package/dist/helpers/columnHelper.cjs +9 -4
- package/dist/helpers/columnHelper.cjs.map +1 -1
- package/dist/helpers/columnHelper.d.cts +9 -4
- package/dist/helpers/columnHelper.d.ts +9 -4
- package/dist/helpers/columnHelper.js +9 -4
- package/dist/helpers/columnHelper.js.map +1 -1
- package/dist/helpers/tableOptions.cjs.map +1 -1
- package/dist/helpers/tableOptions.d.cts +12 -9
- package/dist/helpers/tableOptions.d.ts +12 -9
- package/dist/helpers/tableOptions.js.map +1 -1
- package/dist/types/ColumnDef.d.cts +38 -0
- package/dist/types/ColumnDef.d.ts +38 -0
- package/dist/types/TableOptions.d.cts +15 -0
- package/dist/types/TableOptions.d.ts +15 -0
- package/dist/types/TableState.d.cts +12 -0
- package/dist/types/TableState.d.ts +12 -0
- package/package.json +5 -3
- package/skills/column-definitions/SKILL.md +333 -0
- package/skills/column-layout/SKILL.md +328 -0
- package/skills/column-layout/references/subsystems.md +220 -0
- package/skills/customizing-feature-behavior/SKILL.md +416 -0
- package/skills/filtering/SKILL.md +357 -0
- package/skills/filtering/references/faceting-and-fuzzy.md +191 -0
- package/skills/grouping/SKILL.md +448 -0
- package/skills/migrate-v8-to-v9/SKILL.md +495 -0
- package/skills/pagination/SKILL.md +385 -0
- package/skills/row-expanding/SKILL.md +348 -0
- package/skills/row-pinning/SKILL.md +269 -0
- package/skills/row-selection/SKILL.md +391 -0
- package/skills/setup/SKILL.md +400 -0
- package/skills/sorting/SKILL.md +344 -0
- package/skills/state-management/SKILL.md +388 -0
- package/src/core/cells/coreCellsFeature.utils.ts +11 -8
- package/src/core/columns/coreColumnsFeature.types.ts +7 -6
- package/src/core/columns/coreColumnsFeature.utils.ts +37 -27
- package/src/core/headers/coreHeadersFeature.types.ts +6 -4
- package/src/core/headers/coreHeadersFeature.utils.ts +23 -18
- package/src/core/row-models/coreRowModelsFeature.utils.ts +48 -36
- package/src/core/rows/coreRowsFeature.types.ts +4 -4
- package/src/core/rows/coreRowsFeature.utils.ts +34 -28
- package/src/core/table/coreTablesFeature.types.ts +6 -2
- package/src/core/table/coreTablesFeature.utils.ts +2 -2
- package/src/features/column-faceting/columnFacetingFeature.types.ts +16 -10
- package/src/features/column-faceting/columnFacetingFeature.utils.ts +26 -18
- package/src/features/column-filtering/columnFilteringFeature.types.ts +21 -11
- package/src/features/column-filtering/columnFilteringFeature.utils.ts +39 -28
- package/src/features/column-grouping/columnGroupingFeature.types.ts +18 -14
- package/src/features/column-grouping/columnGroupingFeature.utils.ts +55 -43
- package/src/features/column-ordering/columnOrderingFeature.types.ts +14 -5
- package/src/features/column-ordering/columnOrderingFeature.utils.ts +30 -23
- package/src/features/column-pinning/columnPinningFeature.types.ts +43 -31
- package/src/features/column-pinning/columnPinningFeature.utils.ts +111 -91
- package/src/features/column-resizing/columnResizingFeature.types.ts +9 -9
- package/src/features/column-resizing/columnResizingFeature.utils.ts +29 -21
- package/src/features/column-sizing/columnSizingFeature.types.ts +19 -12
- package/src/features/column-sizing/columnSizingFeature.utils.ts +52 -41
- package/src/features/column-visibility/columnVisibilityFeature.types.ts +16 -13
- package/src/features/column-visibility/columnVisibilityFeature.utils.ts +54 -42
- package/src/features/global-filtering/globalFilteringFeature.types.ts +10 -5
- package/src/features/global-filtering/globalFilteringFeature.utils.ts +20 -14
- package/src/features/row-expanding/rowExpandingFeature.types.ts +16 -15
- package/src/features/row-expanding/rowExpandingFeature.utils.ts +56 -41
- package/src/features/row-pagination/rowPaginationFeature.types.ts +19 -12
- package/src/features/row-pagination/rowPaginationFeature.utils.ts +49 -32
- package/src/features/row-pinning/rowPinningFeature.types.ts +12 -8
- package/src/features/row-pinning/rowPinningFeature.utils.ts +39 -29
- package/src/features/row-selection/rowSelectionFeature.types.ts +30 -24
- package/src/features/row-selection/rowSelectionFeature.utils.ts +89 -69
- package/src/features/row-sorting/rowSortingFeature.types.ts +10 -8
- package/src/features/row-sorting/rowSortingFeature.utils.ts +62 -45
- package/src/fns/aggregationFns.ts +33 -9
- package/src/fns/filterFns.ts +48 -17
- package/src/helpers/columnHelper.ts +9 -4
- package/src/helpers/tableOptions.ts +12 -9
- package/src/types/ColumnDef.ts +38 -0
- package/src/types/TableOptions.ts +15 -0
- 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.48'
|
|
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
|