Skip to content

Commit cd3bdfd

Browse files
KevinVandyJoel 'Aaron' Cohenclaude
authored
fix: ensure isSubRowSelected returns false if no subRows are selectable (#6491)
A parent row whose sub-rows are all unselectable fell through with allChildrenSelected still true, so isSubRowSelected reported 'all' and getIsAllSubRowsSelected returned true with nothing selected. Track whether any selectable descendant was seen and return false when none were. Port of #5790 to v9. Fixes #5173 Co-authored-by: Joel 'Aaron' Cohen <acohen@deepsig.ai> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 54fb3bf commit cd3bdfd

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

packages/table-core/src/features/row-selection/rowSelectionFeature.utils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,7 @@ export function isSubRowSelected<
907907

908908
let someSelected = false
909909
let allChildrenSelected = true
910+
let someSelectable = false
910911

911912
for (let i = 0; i < row.subRows.length; i++) {
912913
const subRow = row.subRows[i]!
@@ -917,6 +918,7 @@ export function isSubRowSelected<
917918
}
918919

919920
if (row_getCanSelect(subRow)) {
921+
someSelectable = true
920922
if (isRowSelected(subRow, rowSelection)) {
921923
someSelected = true
922924
} else {
@@ -929,14 +931,19 @@ export function isSubRowSelected<
929931
const subRowChildrenSelected = isSubRowSelected(subRow)
930932
if (subRowChildrenSelected === 'all') {
931933
someSelected = true
934+
someSelectable = true
932935
} else if (subRowChildrenSelected === 'some') {
933936
someSelected = true
934937
allChildrenSelected = false
938+
someSelectable = true
935939
} else {
936940
allChildrenSelected = false
937941
}
938942
}
939943
}
940944

945+
// A row with no selectable descendants can never be in a selected state
946+
if (!someSelectable) return false
947+
941948
return allChildrenSelected ? 'all' : someSelected ? 'some' : false
942949
}

packages/table-core/tests/implementation/features/row-selection/rowSelectionFeature.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,52 @@ describe('rowSelectionFeature', () => {
416416
expect(result).toEqual(false)
417417
})
418418

419+
it('should return false if no sub-rows are selectable', () => {
420+
const data = generateTestData(3, 2)
421+
const columns = generateColumnDefs(data)
422+
423+
const table = constructTable<typeof features, Person>({
424+
features,
425+
enableRowSelection: false,
426+
renderFallbackValue: '',
427+
data,
428+
getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
429+
initialState: {
430+
rowSelection: {},
431+
},
432+
columns,
433+
})
434+
435+
const firstRow = table.getCoreRowModel().rows[0]!
436+
437+
const result = RowSelectionUtils.isSubRowSelected(firstRow)
438+
439+
expect(result).toEqual(false)
440+
})
441+
442+
it('should return some if no children are selectable, but a grand-child is and is selected', () => {
443+
const data = generateTestData(3, 2, 2)
444+
const columns = generateColumnDefs(data)
445+
446+
const table = constructTable<typeof features, Person>({
447+
features,
448+
enableRowSelection: (row) => row.id === '0.0.1',
449+
renderFallbackValue: '',
450+
data,
451+
getSubRows: (originalRow: Person, _idx: number) => originalRow.subRows,
452+
initialState: {
453+
rowSelection: { '0.0.1': true },
454+
},
455+
columns,
456+
})
457+
458+
const firstRow = table.getCoreRowModel().rows[0]!
459+
460+
const result = RowSelectionUtils.isSubRowSelected(firstRow)
461+
462+
expect(result).toEqual('some')
463+
})
464+
419465
it('should return some if some sub-rows are selected', () => {
420466
const data = generateTestData(3, 2)
421467
const columns = generateColumnDefs(data)

packages/table-core/tests/unit/features/row-selection/rowSelectionFeature.utils.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,14 @@ describe('row_getIsSomeSelected / row_getIsAllSubRowsSelected', () => {
399399
expect(row_getIsSomeSelected(row)).toBe(false)
400400
expect(row_getIsAllSubRowsSelected(row)).toBe(false)
401401
})
402+
403+
it('should report nothing when no sub-rows are selectable', () => {
404+
const table = makeTable({ enableRowSelection: false }, [3, 2])
405+
const parent = table.getRow('0')
406+
407+
expect(row_getIsSomeSelected(parent)).toBe(false)
408+
expect(row_getIsAllSubRowsSelected(parent)).toBe(false)
409+
})
402410
})
403411

404412
describe('row selection flags', () => {

0 commit comments

Comments
 (0)