Skip to content

Commit 641ef9d

Browse files
ShaidulintShaidulint
andauthored
fix(selectionColumn): exclude disabled rows from selection (#151)
### Description Changes in `selectionColumn` to handle non-selectable table rows (`!row.getCanSelect()`): * **Bulk selection fix**: Rows that should not be selectable are now skipped during bulk selection (Ctrl + Click). * **Header checkbox fix**: The "Select All" checkbox in the header no longer gets stuck in the `indeterminate` state if any row is not allow to select. #### Commits * fix(selectionColumn): exclude disabled rows from selection * fix(getToggleAllEnabledRowsSelectedHandler): rid of indeterminate argument --------- Co-authored-by: Shaidulint <shaidulint@yandex-team.ru>
1 parent 1b110a5 commit 641ef9d

4 files changed

Lines changed: 29 additions & 3 deletions

File tree

src/constants/selectionColumn.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import {RangedSelectionCheckbox, SelectionCheckbox} from '../components';
22
import type {ColumnDef} from '../types/base';
3+
import {getToggleAllEnabledRowsSelectedHandler} from '../utils';
34

45
export const selectionColumn: ColumnDef<unknown> = {
56
id: '_select',
67
header: ({table}) => (
78
<SelectionCheckbox
89
checked={table.getIsAllRowsSelected()}
9-
disabled={!table.options.enableRowSelection}
10+
disabled={!table.options.enableRowSelection || !table.options.enableMultiRowSelection}
1011
indeterminate={table.getIsSomeRowsSelected()}
11-
onChange={table.getToggleAllRowsSelectedHandler()}
12+
onChange={getToggleAllEnabledRowsSelectedHandler(table)}
1213
/>
1314
),
1415
cell: (cellContext) => (

src/hooks/useToggleRangeSelectionHandler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ export const useToggleRangeSelectionHandler = <TData extends RowData, TValue>(
3535
} else {
3636
const startIndex = Math.min(clickedRowIndex, lastSelectedRowIndexRef.current);
3737
const endIndex = Math.max(clickedRowIndex, lastSelectedRowIndexRef.current);
38-
const rowsToSelect = table.getRowModel().rows.slice(startIndex, endIndex + 1);
38+
const rowsToSelect = table
39+
.getRowModel()
40+
.rows.slice(startIndex, endIndex + 1)
41+
.filter((rowToSelect) => rowToSelect.getCanSelect());
3942
const currentRowSelectionState = table.getState().rowSelection;
4043

4144
const rangeAlreadySelected = rowsToSelect.every(({id}) => {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type {Table} from '@tanstack/table-core';
2+
3+
export function getToggleAllEnabledRowsSelectedHandler<T>(table: Table<T>) {
4+
return (event: React.ChangeEvent<HTMLInputElement>) => {
5+
const isSomeRowsAreSelected = table.getIsSomeRowsSelected();
6+
if (isSomeRowsAreSelected) {
7+
const preGroupedFlatRows = table
8+
.getPreGroupedRowModel()
9+
.flatRows.filter((row) => row.getCanSelect());
10+
const tableRowSelection = table.getState().rowSelection;
11+
12+
const allEnableRowsAreSelected = preGroupedFlatRows.every((row) => {
13+
return tableRowSelection[row.id] === true;
14+
});
15+
16+
table.toggleAllRowsSelected(!allEnableRowsAreSelected);
17+
} else {
18+
table.toggleAllRowsSelected(event.target.checked);
19+
}
20+
};
21+
}

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export * from './getVirtualRowRangeExtractor';
1212
export * from './shouldRenderFooterCell';
1313
export * from './shouldRenderFooterRow';
1414
export * from './shouldRenderHeaderCell';
15+
export * from './getToggleAllEnabledRowsSelectedHandler';

0 commit comments

Comments
 (0)