@tanstack/table-core 9.0.0-beta.43 → 9.0.0-beta.44
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/dist/core/rows/coreRowsFeature.types.d.cts +12 -1
- package/dist/core/rows/coreRowsFeature.types.d.ts +12 -1
- package/dist/core/table/constructTable.cjs +1 -0
- package/dist/core/table/constructTable.cjs.map +1 -1
- package/dist/core/table/constructTable.js +1 -0
- package/dist/core/table/constructTable.js.map +1 -1
- package/dist/core/table/coreTablesFeature.types.d.cts +2 -1
- package/dist/core/table/coreTablesFeature.types.d.ts +2 -1
- package/dist/core/table/coreTablesFeature.utils.cjs +4 -1
- package/dist/core/table/coreTablesFeature.utils.cjs.map +1 -1
- package/dist/core/table/coreTablesFeature.utils.d.cts +2 -1
- package/dist/core/table/coreTablesFeature.utils.d.ts +2 -1
- package/dist/core/table/coreTablesFeature.utils.js +4 -1
- package/dist/core/table/coreTablesFeature.utils.js.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.cjs +13 -2
- package/dist/features/row-selection/rowSelectionFeature.cjs.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.js +13 -2
- package/dist/features/row-selection/rowSelectionFeature.js.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.types.d.cts +35 -5
- package/dist/features/row-selection/rowSelectionFeature.types.d.ts +35 -5
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs +50 -3
- package/dist/features/row-selection/rowSelectionFeature.utils.cjs.map +1 -1
- package/dist/features/row-selection/rowSelectionFeature.utils.d.cts +8 -6
- package/dist/features/row-selection/rowSelectionFeature.utils.d.ts +8 -6
- package/dist/features/row-selection/rowSelectionFeature.utils.js +50 -3
- package/dist/features/row-selection/rowSelectionFeature.utils.js.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/types/TableFeatures.d.cts +22 -2
- package/dist/types/TableFeatures.d.ts +22 -2
- package/package.json +1 -1
- package/skills/api-not-found/SKILL.md +1 -1
- package/skills/client-vs-server/SKILL.md +1 -1
- package/skills/column-faceting/SKILL.md +1 -1
- package/skills/column-filtering/SKILL.md +1 -1
- package/skills/column-ordering/SKILL.md +1 -1
- package/skills/column-pinning/SKILL.md +1 -1
- package/skills/column-resizing/SKILL.md +1 -1
- package/skills/column-sizing/SKILL.md +1 -1
- package/skills/column-visibility/SKILL.md +1 -1
- package/skills/core/SKILL.md +37 -2
- package/skills/custom-features/SKILL.md +30 -2
- package/skills/expanding/SKILL.md +1 -1
- package/skills/global-filtering/SKILL.md +1 -1
- package/skills/grouping/SKILL.md +1 -1
- package/skills/migrate-v8-to-v9/SKILL.md +1 -1
- package/skills/pagination/SKILL.md +1 -1
- package/skills/row-pinning/SKILL.md +1 -1
- package/skills/row-selection/SKILL.md +91 -3
- package/skills/sorting/SKILL.md +1 -1
- package/skills/table-features/SKILL.md +1 -1
- package/skills/typescript/SKILL.md +1 -1
- package/src/core/rows/coreRowsFeature.types.ts +12 -1
- package/src/core/table/constructTable.ts +4 -0
- package/src/core/table/coreTablesFeature.types.ts +2 -1
- package/src/core/table/coreTablesFeature.utils.ts +7 -1
- package/src/features/row-selection/rowSelectionFeature.ts +19 -1
- package/src/features/row-selection/rowSelectionFeature.types.ts +37 -3
- package/src/features/row-selection/rowSelectionFeature.utils.ts +114 -14
- package/src/types/TableFeatures.ts +32 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: row-selection
|
|
3
3
|
description: >
|
|
4
|
-
Maintain rowSelection ID state with stable getRowId, single, multi, and
|
|
4
|
+
Maintain rowSelection ID state with stable getRowId, single, multi, subrow, and Shift-range rules, selected row models, handler anchors, and manual-pagination semantics. Load when implementing getToggleSelectedHandler, enableRowRangeSelection, selectChildren, or selected IDs that outlive loaded Row objects.
|
|
5
5
|
metadata:
|
|
6
6
|
{
|
|
7
7
|
type: sub-skill,
|
|
8
8
|
library: '@tanstack/table-core',
|
|
9
|
-
library_version: '9.0.0-beta.
|
|
9
|
+
library_version: '9.0.0-beta.44',
|
|
10
10
|
}
|
|
11
11
|
requires: ['core', 'table-features']
|
|
12
12
|
sources:
|
|
@@ -20,7 +20,11 @@ This skill builds on `core` and `table-features`. Selection is independent ID st
|
|
|
20
20
|
## Setup
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
rowSelectionFeature,
|
|
25
|
+
tableFeatures,
|
|
26
|
+
type Row,
|
|
27
|
+
} from '@tanstack/table-core'
|
|
24
28
|
|
|
25
29
|
type Person = { id: string; name: string }
|
|
26
30
|
export const features = tableFeatures({ rowSelectionFeature })
|
|
@@ -39,6 +43,28 @@ const loadedSelectedRows = table.getSelectedRowModel().rows
|
|
|
39
43
|
|
|
40
44
|
Use IDs for database-wide intent and row models for currently loaded objects.
|
|
41
45
|
|
|
46
|
+
### Inclusive Shift ranges through the row handler
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
export function getSelectionHandler(row: Row<typeof features, Person>) {
|
|
50
|
+
return row.getToggleSelectedHandler()
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The handler establishes a table-local anchor on ordinary interactions and applies the checked value to the inclusive current display-order range on Shift interactions. Range behavior is enabled by default; set `enableRowRangeSelection: false` to preserve non-range handler behavior. Direct `row.toggleSelected()` and `table.setRowSelection()` calls do not move that anchor.
|
|
55
|
+
|
|
56
|
+
Pass the original checkbox click event to this handler. DOM `change` events often omit modifier keys, so use the framework's click binding for row checkboxes unless its change event exposes the original click through `nativeEvent` (as React does).
|
|
57
|
+
|
|
58
|
+
### Limit a range to explicitly displayed rows
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
export function getDisplayedRowsOnlyHandler(row: Row<typeof features, Person>) {
|
|
62
|
+
return row.getToggleSelectedHandler({ selectChildren: false })
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The default `selectChildren: true` recursively changes selectable descendants of parents encountered in the range. Set it to `false` when collapsed descendants outside the display-order interval must remain unchanged.
|
|
67
|
+
|
|
42
68
|
## Common Mistakes
|
|
43
69
|
|
|
44
70
|
### [HIGH] Expecting selection to clean itself
|
|
@@ -71,6 +97,68 @@ Under manual pagination, unloaded selected IDs have no `Row` object in the curre
|
|
|
71
97
|
|
|
72
98
|
Source: `docs/framework/react/guide/row-selection.md#note-if-you-are-using-manualpagination`
|
|
73
99
|
|
|
100
|
+
### [HIGH] Bypassing the range-selection handler
|
|
101
|
+
|
|
102
|
+
Wrong:
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
const onChange = (event: { target: { checked: boolean } }) =>
|
|
106
|
+
row.toggleSelected(event.target.checked)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Correct:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const onChange = row.getToggleSelectedHandler()
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Only successful interactions through `getToggleSelectedHandler()` establish or advance the Shift-range anchor. The handler also supports custom range-event detection through `isRowRangeSelectionEvent`.
|
|
116
|
+
|
|
117
|
+
Source: `docs/framework/react/guide/row-selection.md#shift-range-selection`
|
|
118
|
+
|
|
119
|
+
### [HIGH] Binding a DOM change event that drops Shift
|
|
120
|
+
|
|
121
|
+
Wrong:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
checkbox.addEventListener('change', row.getToggleSelectedHandler())
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Correct:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
checkbox.addEventListener('click', row.getToggleSelectedHandler())
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
The range modifier must be present on the event passed to the handler. Raw DOM `change` events do not reliably expose click modifier keys.
|
|
134
|
+
|
|
135
|
+
Source: `docs/framework/svelte/guide/row-selection.md#shift-range-selection`
|
|
136
|
+
|
|
137
|
+
### [MEDIUM] Expecting ranges across unloaded server pages
|
|
138
|
+
|
|
139
|
+
Wrong:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
const options = {
|
|
143
|
+
manualPagination: true,
|
|
144
|
+
enableRowRangeSelection: true,
|
|
145
|
+
}
|
|
146
|
+
// Shift cannot select rows absent from data.
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Correct:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
const options = {
|
|
153
|
+
manualPagination: true,
|
|
154
|
+
getRowId: (row: Person) => row.id,
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Client-side ranges can cross pages because display order is pre-pagination. Manual/server pagination cannot include rows absent from the loaded `data`; select database-wide IDs in application state when that behavior is required.
|
|
159
|
+
|
|
160
|
+
Source: `docs/framework/react/guide/row-selection.md#shift-range-selection`, `https://github.com/TanStack/table/issues/4781`
|
|
161
|
+
|
|
74
162
|
## API Discovery
|
|
75
163
|
|
|
76
164
|
Inspect `node_modules/@tanstack/table-core/src/features/row-selection/` for state, row-model variants, and selection enablement callbacks.
|
package/skills/sorting/SKILL.md
CHANGED
|
@@ -13,6 +13,15 @@ export interface Row_CoreProperties<
|
|
|
13
13
|
Column<TFeatures, TData, unknown>,
|
|
14
14
|
Cell<TFeatures, TData, unknown>
|
|
15
15
|
>
|
|
16
|
+
/**
|
|
17
|
+
* Internal cache used while resolving the current display order.
|
|
18
|
+
*
|
|
19
|
+
* This value may be stale until display order is recomputed. Use
|
|
20
|
+
* `row.getDisplayIndex()` instead; it refreshes and validates the cached
|
|
21
|
+
* position before returning it.
|
|
22
|
+
*
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
16
25
|
_displayIndexCache: number
|
|
17
26
|
_uniqueValuesCache: Record<string, unknown>
|
|
18
27
|
_valuesCache: Record<string, unknown>
|
|
@@ -56,7 +65,9 @@ export interface Row_Row<
|
|
|
56
65
|
> extends Row_CoreProperties<TFeatures, TData> {
|
|
57
66
|
/**
|
|
58
67
|
* Returns the zero-based index of the row in the current display order
|
|
59
|
-
* before pagination, or `-1` if the row is not in that model.
|
|
68
|
+
* before pagination, or `-1` if the row is not in that model. Use this for
|
|
69
|
+
* display row-number columns instead of `row.index` or the internal
|
|
70
|
+
* `_displayIndexCache` field.
|
|
60
71
|
*/
|
|
61
72
|
getDisplayIndex: () => number
|
|
62
73
|
/**
|
|
@@ -166,6 +166,10 @@ export function constructTable<
|
|
|
166
166
|
),
|
|
167
167
|
)
|
|
168
168
|
|
|
169
|
+
for (let i = 0; i < featuresList.length; i++) {
|
|
170
|
+
featuresList[i]!.initTableInstanceData?.(table)
|
|
171
|
+
}
|
|
172
|
+
|
|
169
173
|
if (
|
|
170
174
|
process.env.NODE_ENV === 'development' &&
|
|
171
175
|
(tableOptions.debugAll || tableOptions.debugTable)
|
|
@@ -229,7 +229,8 @@ export interface Table_Table<
|
|
|
229
229
|
*
|
|
230
230
|
* Prefer feature-specific reset APIs, such as `resetPagination`, when a state
|
|
231
231
|
* slice may be owned by an external atom or needs that feature's blank/default
|
|
232
|
-
* reset behavior.
|
|
232
|
+
* reset behavior. After resetting internal atoms, this also invokes feature
|
|
233
|
+
* reset hooks for mutable, transient table-instance data.
|
|
233
234
|
*/
|
|
234
235
|
reset: () => void
|
|
235
236
|
/**
|
|
@@ -40,7 +40,8 @@ export function table_syncExternalStateToBaseAtoms<
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
|
-
* Resets all internal table base atoms to `table.initialState
|
|
43
|
+
* Resets all internal table base atoms to `table.initialState`, then clears
|
|
44
|
+
* transient instance data through registered feature reset hooks.
|
|
44
45
|
*
|
|
45
46
|
* This resets internally owned state slices in a single reactivity batch. Use
|
|
46
47
|
* feature-specific reset APIs when a slice may be externally owned.
|
|
@@ -62,6 +63,11 @@ export function table_reset<
|
|
|
62
63
|
;(table.baseAtoms as any)[key].set(snap[key])
|
|
63
64
|
}
|
|
64
65
|
})
|
|
66
|
+
|
|
67
|
+
const features = Object.values(table._features)
|
|
68
|
+
for (let i = 0; i < features.length; i++) {
|
|
69
|
+
features[i]!.resetTableInstanceData?.(table)
|
|
70
|
+
}
|
|
65
71
|
}
|
|
66
72
|
|
|
67
73
|
/**
|
|
@@ -35,6 +35,16 @@ import type { TableFeature } from '../../types/TableFeatures'
|
|
|
35
35
|
* Feature that adds row selection state and APIs for row and page selection.
|
|
36
36
|
*/
|
|
37
37
|
export const rowSelectionFeature: TableFeature = {
|
|
38
|
+
initTableInstanceData: (table) => {
|
|
39
|
+
// @ts-ignore - _lastSelectedRowId is row selection table instance data
|
|
40
|
+
table._lastSelectedRowId = null
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
resetTableInstanceData: (table) => {
|
|
44
|
+
// @ts-ignore - _lastSelectedRowId is row selection table instance data
|
|
45
|
+
table._lastSelectedRowId = null
|
|
46
|
+
},
|
|
47
|
+
|
|
38
48
|
getInitialState: (initialState) => {
|
|
39
49
|
return {
|
|
40
50
|
rowSelection: getDefaultRowSelectionState(),
|
|
@@ -47,7 +57,15 @@ export const rowSelectionFeature: TableFeature = {
|
|
|
47
57
|
onRowSelectionChange: makeStateUpdater('rowSelection', table),
|
|
48
58
|
enableRowSelection: true,
|
|
49
59
|
enableMultiRowSelection: true,
|
|
60
|
+
enableRowRangeSelection: true,
|
|
50
61
|
enableSubRowSelection: true,
|
|
62
|
+
isRowRangeSelectionEvent: (event) => {
|
|
63
|
+
const rangeEvent = event as {
|
|
64
|
+
shiftKey?: boolean
|
|
65
|
+
nativeEvent?: { shiftKey?: boolean }
|
|
66
|
+
}
|
|
67
|
+
return Boolean(rangeEvent.shiftKey || rangeEvent.nativeEvent?.shiftKey)
|
|
68
|
+
},
|
|
51
69
|
}
|
|
52
70
|
},
|
|
53
71
|
|
|
@@ -85,7 +103,7 @@ export const rowSelectionFeature: TableFeature = {
|
|
|
85
103
|
fn: (row) => row_getCanMultiSelect(row),
|
|
86
104
|
},
|
|
87
105
|
row_getToggleSelectedHandler: {
|
|
88
|
-
fn: (row) => row_getToggleSelectedHandler(row),
|
|
106
|
+
fn: (row, opts) => row_getToggleSelectedHandler(row, opts),
|
|
89
107
|
},
|
|
90
108
|
})
|
|
91
109
|
},
|
|
@@ -5,6 +5,17 @@ import type { Row } from '../../types/Row'
|
|
|
5
5
|
|
|
6
6
|
export type RowSelectionState = Record<string, true>
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Controls how toggling a row affects its descendants.
|
|
10
|
+
*/
|
|
11
|
+
export interface ToggleSelectedOptions {
|
|
12
|
+
/**
|
|
13
|
+
* Whether selectable child rows should be toggled recursively. Defaults to
|
|
14
|
+
* `true`.
|
|
15
|
+
*/
|
|
16
|
+
selectChildren?: boolean
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
export interface TableState_RowSelection {
|
|
9
20
|
rowSelection: RowSelectionState
|
|
10
21
|
}
|
|
@@ -13,6 +24,11 @@ export interface TableOptions_RowSelection<
|
|
|
13
24
|
in out TFeatures extends TableFeatures,
|
|
14
25
|
in out TData extends RowData,
|
|
15
26
|
> {
|
|
27
|
+
/**
|
|
28
|
+
* Enables inclusive row range selection through
|
|
29
|
+
* `row.getToggleSelectedHandler()`. Defaults to `true`.
|
|
30
|
+
*/
|
|
31
|
+
enableRowRangeSelection?: boolean
|
|
16
32
|
/**
|
|
17
33
|
* Allows rows to be selected alongside other rows.
|
|
18
34
|
*
|
|
@@ -32,6 +48,14 @@ export interface TableOptions_RowSelection<
|
|
|
32
48
|
* grouping features and defaults to `true`.
|
|
33
49
|
*/
|
|
34
50
|
enableSubRowSelection?: boolean | ((row: Row<TFeatures, TData>) => boolean)
|
|
51
|
+
/**
|
|
52
|
+
* Determines whether a row-selection handler event should select or
|
|
53
|
+
* deselect the inclusive range from the most recent handler interaction.
|
|
54
|
+
*
|
|
55
|
+
* By default, events with `shiftKey` directly on the event or on
|
|
56
|
+
* `event.nativeEvent` are treated as range-selection events.
|
|
57
|
+
*/
|
|
58
|
+
isRowRangeSelectionEvent?: (event: unknown) => boolean
|
|
35
59
|
/**
|
|
36
60
|
* Called with an updater when row selection state changes. Pair this with
|
|
37
61
|
* `state.rowSelection` when using external state; external atoms can own the
|
|
@@ -44,7 +68,6 @@ export interface TableOptions_RowSelection<
|
|
|
44
68
|
// row: Row<TFeatures, TData>
|
|
45
69
|
// ) => boolean)
|
|
46
70
|
// isAdditiveSelectEvent?: (e: unknown) => boolean
|
|
47
|
-
// isInclusiveSelectEvent?: (e: unknown) => boolean
|
|
48
71
|
// selectRowsFn?: (
|
|
49
72
|
// table: Table<TFeatures, TData>,
|
|
50
73
|
// rowModel: RowModel<TFeatures, TData>
|
|
@@ -78,18 +101,29 @@ export interface Row_RowSelection {
|
|
|
78
101
|
getIsSomeSelected: () => boolean
|
|
79
102
|
/**
|
|
80
103
|
* Creates a checkbox-style handler that toggles this row's selected state.
|
|
104
|
+
* Pass the original checkbox click event, or a framework event whose
|
|
105
|
+
* `nativeEvent` is that click, so Shift range selection can detect the
|
|
106
|
+
* modifier key.
|
|
81
107
|
*/
|
|
82
|
-
getToggleSelectedHandler: (
|
|
108
|
+
getToggleSelectedHandler: (
|
|
109
|
+
opts?: ToggleSelectedOptions,
|
|
110
|
+
) => (event: unknown) => void
|
|
83
111
|
/**
|
|
84
112
|
* Selects/deselects the row.
|
|
85
113
|
*/
|
|
86
|
-
toggleSelected: (value?: boolean, opts?:
|
|
114
|
+
toggleSelected: (value?: boolean, opts?: ToggleSelectedOptions) => void
|
|
87
115
|
}
|
|
88
116
|
|
|
89
117
|
export interface Table_RowSelection<
|
|
90
118
|
in out TFeatures extends TableFeatures,
|
|
91
119
|
in out TData extends RowData,
|
|
92
120
|
> {
|
|
121
|
+
/**
|
|
122
|
+
* The most recent row interacted with through the row selection handler.
|
|
123
|
+
*
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
_lastSelectedRowId: string | null
|
|
93
127
|
/**
|
|
94
128
|
* Builds a selected-row model from rows after filtering.
|
|
95
129
|
*/
|
|
@@ -10,7 +10,10 @@ import type { TableFeatures } from '../../types/TableFeatures'
|
|
|
10
10
|
import type { RowModel } from '../../core/row-models/coreRowModelsFeature.types'
|
|
11
11
|
import type { Table_Internal } from '../../types/Table'
|
|
12
12
|
import type { Row } from '../../types/Row'
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
RowSelectionState,
|
|
15
|
+
ToggleSelectedOptions,
|
|
16
|
+
} from './rowSelectionFeature.types'
|
|
14
17
|
|
|
15
18
|
// State APIs
|
|
16
19
|
|
|
@@ -66,6 +69,8 @@ export function table_resetRowSelection<
|
|
|
66
69
|
TFeatures extends TableFeatures,
|
|
67
70
|
TData extends RowData,
|
|
68
71
|
>(table: Table_Internal<TFeatures, TData>, defaultState?: boolean) {
|
|
72
|
+
// @ts-ignore - _lastSelectedRowId is part of the RowSelection feature
|
|
73
|
+
table._lastSelectedRowId = null
|
|
69
74
|
table_setRowSelection(
|
|
70
75
|
table,
|
|
71
76
|
defaultState
|
|
@@ -98,6 +103,8 @@ export function table_toggleAllRowsSelected<
|
|
|
98
103
|
value?: boolean,
|
|
99
104
|
opts?: { deselectAll?: boolean },
|
|
100
105
|
) {
|
|
106
|
+
// @ts-ignore - _lastSelectedRowId is part of the RowSelection feature
|
|
107
|
+
table._lastSelectedRowId = null
|
|
101
108
|
table_setRowSelection(table, (old) => {
|
|
102
109
|
value =
|
|
103
110
|
typeof value !== 'undefined'
|
|
@@ -153,6 +160,8 @@ export function table_toggleAllPageRowsSelected<
|
|
|
153
160
|
value?: boolean,
|
|
154
161
|
opts?: { deselectAll?: boolean },
|
|
155
162
|
) {
|
|
163
|
+
// @ts-ignore - _lastSelectedRowId is part of the RowSelection feature
|
|
164
|
+
table._lastSelectedRowId = null
|
|
156
165
|
table_setRowSelection(table, (old) => {
|
|
157
166
|
const resolvedValue =
|
|
158
167
|
typeof value !== 'undefined'
|
|
@@ -492,13 +501,7 @@ export function table_getToggleAllPageRowsSelectedHandler<
|
|
|
492
501
|
export function row_toggleSelected<
|
|
493
502
|
TFeatures extends TableFeatures,
|
|
494
503
|
TData extends RowData,
|
|
495
|
-
>(
|
|
496
|
-
row: Row<TFeatures, TData>,
|
|
497
|
-
value?: boolean,
|
|
498
|
-
opts?: {
|
|
499
|
-
selectChildren?: boolean
|
|
500
|
-
},
|
|
501
|
-
) {
|
|
504
|
+
>(row: Row<TFeatures, TData>, value?: boolean, opts?: ToggleSelectedOptions) {
|
|
502
505
|
const isSelected = row_getIsSelected(row)
|
|
503
506
|
|
|
504
507
|
table_setRowSelection(row.table, (old) => {
|
|
@@ -643,7 +646,11 @@ export function row_getCanMultiSelect<
|
|
|
643
646
|
* Creates a checkbox-style handler that selects or deselects this row.
|
|
644
647
|
*
|
|
645
648
|
* The handler is a no-op when the row cannot be selected and reads
|
|
646
|
-
* `event.target.checked`.
|
|
649
|
+
* `event.target.checked`. Shift events select or deselect the inclusive range
|
|
650
|
+
* from the most recent selectable row handled by this table. The event's
|
|
651
|
+
* optional `persist()` method is called before it is read. Pass
|
|
652
|
+
* `selectChildren: false` to limit changes to rows explicitly present in the
|
|
653
|
+
* display-order interval.
|
|
647
654
|
*
|
|
648
655
|
* @example
|
|
649
656
|
* ```ts
|
|
@@ -653,18 +660,111 @@ export function row_getCanMultiSelect<
|
|
|
653
660
|
export function row_getToggleSelectedHandler<
|
|
654
661
|
TFeatures extends TableFeatures,
|
|
655
662
|
TData extends RowData,
|
|
656
|
-
>(row: Row<TFeatures, TData
|
|
663
|
+
>(row: Row<TFeatures, TData>, opts?: ToggleSelectedOptions) {
|
|
657
664
|
const canSelect = row_getCanSelect(row)
|
|
658
665
|
|
|
659
666
|
return (e: unknown) => {
|
|
660
667
|
if (!canSelect) return
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
(
|
|
664
|
-
|
|
668
|
+
|
|
669
|
+
const event = e as {
|
|
670
|
+
persist?: () => void
|
|
671
|
+
target: { checked: boolean }
|
|
672
|
+
}
|
|
673
|
+
event.persist?.()
|
|
674
|
+
|
|
675
|
+
const table = row.table
|
|
676
|
+
const checked = event.target.checked
|
|
677
|
+
// @ts-ignore - _lastSelectedRowId is part of the RowSelection feature
|
|
678
|
+
const anchorId = table._lastSelectedRowId
|
|
679
|
+
const canSelectRange =
|
|
680
|
+
table.options.enableRowRangeSelection !== false &&
|
|
681
|
+
anchorId !== null &&
|
|
682
|
+
row_getCanMultiSelect(row) &&
|
|
683
|
+
(table.options.isRowRangeSelectionEvent?.(e) ?? false)
|
|
684
|
+
|
|
685
|
+
if (
|
|
686
|
+
!canSelectRange ||
|
|
687
|
+
!selectRowRange(row, anchorId, checked, opts?.selectChildren ?? true)
|
|
688
|
+
) {
|
|
689
|
+
row_toggleSelected(row, checked, opts)
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// @ts-ignore - _lastSelectedRowId is part of the RowSelection feature
|
|
693
|
+
table._lastSelectedRowId = row.id
|
|
665
694
|
}
|
|
666
695
|
}
|
|
667
696
|
|
|
697
|
+
/**
|
|
698
|
+
* Resolves and mutates an inclusive interval in the table's latest logical
|
|
699
|
+
* display order.
|
|
700
|
+
*
|
|
701
|
+
* The anchor is resolved without throwing from the pre-pagination row model,
|
|
702
|
+
* then the core row model. Both endpoint display indexes must still identify
|
|
703
|
+
* those rows in the current order and both endpoints must support
|
|
704
|
+
* multi-selection. Eligible interval rows are applied through one row
|
|
705
|
+
* selection updater; non-selectable and non-multi-selectable rows are skipped.
|
|
706
|
+
* Returns `false` when the interaction should fall back to an ordinary toggle.
|
|
707
|
+
*/
|
|
708
|
+
function selectRowRange<TFeatures extends TableFeatures, TData extends RowData>(
|
|
709
|
+
row: Row<TFeatures, TData>,
|
|
710
|
+
anchorId: string,
|
|
711
|
+
value: boolean,
|
|
712
|
+
includeChildren: boolean,
|
|
713
|
+
): boolean {
|
|
714
|
+
const table = row.table
|
|
715
|
+
const rows = table.getRowsInDisplayOrder()
|
|
716
|
+
const anchorRow =
|
|
717
|
+
table.getPrePaginatedRowModel().rowsById[anchorId] ??
|
|
718
|
+
table.getCoreRowModel().rowsById[anchorId]
|
|
719
|
+
|
|
720
|
+
if (!anchorRow) {
|
|
721
|
+
return false
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const anchorIndex = anchorRow.getDisplayIndex()
|
|
725
|
+
const rowIndex = row.getDisplayIndex()
|
|
726
|
+
const anchorAtIndex = rows[anchorIndex]
|
|
727
|
+
const rowAtIndex = rows[rowIndex]
|
|
728
|
+
|
|
729
|
+
if (
|
|
730
|
+
anchorIndex < 0 ||
|
|
731
|
+
rowIndex < 0 ||
|
|
732
|
+
anchorIndex >= rows.length ||
|
|
733
|
+
rowIndex >= rows.length ||
|
|
734
|
+
anchorAtIndex?.id !== anchorRow.id ||
|
|
735
|
+
rowAtIndex?.id !== row.id ||
|
|
736
|
+
!row_getCanMultiSelect(anchorRow) ||
|
|
737
|
+
!row_getCanMultiSelect(row)
|
|
738
|
+
) {
|
|
739
|
+
return false
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
const start = Math.min(anchorIndex, rowIndex)
|
|
743
|
+
const end = Math.max(anchorIndex, rowIndex)
|
|
744
|
+
|
|
745
|
+
table_setRowSelection(table, (old) => {
|
|
746
|
+
const rowSelection = Object.assign(makeObjectMap<true>(), old)
|
|
747
|
+
|
|
748
|
+
for (let index = start; index <= end; index++) {
|
|
749
|
+
const rangeRow = rows[index]!
|
|
750
|
+
if (!row_getCanSelect(rangeRow) || !row_getCanMultiSelect(rangeRow)) {
|
|
751
|
+
continue
|
|
752
|
+
}
|
|
753
|
+
mutateRowIsSelected(
|
|
754
|
+
rowSelection,
|
|
755
|
+
rangeRow.id,
|
|
756
|
+
value,
|
|
757
|
+
includeChildren,
|
|
758
|
+
table,
|
|
759
|
+
)
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
return rowSelection
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
return true
|
|
766
|
+
}
|
|
767
|
+
|
|
668
768
|
const mutateRowIsSelected = <
|
|
669
769
|
TFeatures extends TableFeatures,
|
|
670
770
|
TData extends RowData,
|
|
@@ -368,8 +368,9 @@ export interface TableFeature {
|
|
|
368
368
|
*
|
|
369
369
|
* The table is a singleton, unlike rows, columns, headers, and cells, so
|
|
370
370
|
* table APIs are assigned directly instead of through a shared prototype.
|
|
371
|
-
* This
|
|
372
|
-
* state have been
|
|
371
|
+
* This hook is exclusively for assigning table methods. It runs after
|
|
372
|
+
* options, state atoms, and the store have been created and after every
|
|
373
|
+
* feature's `initTableInstanceData` hook has completed.
|
|
373
374
|
*/
|
|
374
375
|
constructTableAPIs?: <TFeatures extends TableFeatures, TData extends RowData>(
|
|
375
376
|
table: Table_Internal<TFeatures, TData>,
|
|
@@ -409,6 +410,22 @@ export interface TableFeature {
|
|
|
409
410
|
* override feature defaults.
|
|
410
411
|
*/
|
|
411
412
|
getInitialState?: (initialState: Partial<TableState_All>) => TableState_All
|
|
413
|
+
/**
|
|
414
|
+
* Initializes mutable, non-reactive data owned by this feature on the table
|
|
415
|
+
* instance.
|
|
416
|
+
*
|
|
417
|
+
* This runs once during table construction after options, state atoms, and
|
|
418
|
+
* the store are available, and before any feature's `constructTableAPIs`
|
|
419
|
+
* hook runs. Use `constructTableAPIs` exclusively for assigning table
|
|
420
|
+
* methods. Table resets do not rerun this hook; use
|
|
421
|
+
* `resetTableInstanceData` to clear transient instance data instead.
|
|
422
|
+
*/
|
|
423
|
+
initTableInstanceData?: <
|
|
424
|
+
TFeatures extends TableFeatures,
|
|
425
|
+
TData extends RowData,
|
|
426
|
+
>(
|
|
427
|
+
table: Table_Internal<TFeatures, TData>,
|
|
428
|
+
) => void
|
|
412
429
|
/**
|
|
413
430
|
* Initializes instance-specific data on each column.
|
|
414
431
|
*
|
|
@@ -438,4 +455,17 @@ export interface TableFeature {
|
|
|
438
455
|
>(
|
|
439
456
|
row: Row<TFeatures, TData>,
|
|
440
457
|
) => void
|
|
458
|
+
/**
|
|
459
|
+
* Resets mutable, non-reactive table-instance data owned by this feature.
|
|
460
|
+
*
|
|
461
|
+
* This runs after internally owned state atoms have been restored to
|
|
462
|
+
* `table.initialState` by `table.reset()`. It is intended for transient
|
|
463
|
+
* feature data, not table state slices or externally controlled state.
|
|
464
|
+
*/
|
|
465
|
+
resetTableInstanceData?: <
|
|
466
|
+
TFeatures extends TableFeatures,
|
|
467
|
+
TData extends RowData,
|
|
468
|
+
>(
|
|
469
|
+
table: Table_Internal<TFeatures, TData>,
|
|
470
|
+
) => void
|
|
441
471
|
}
|