Skip to content

Commit 115bc72

Browse files
MBilalShafiweb-flow
authored andcommitted
[DataGrid] Refactor: Use arguments selector for checkbox props (#17683)
1 parent 218d735 commit 115bc72

File tree

2 files changed

+51
-58
lines changed

2 files changed

+51
-58
lines changed

packages/x-data-grid/src/components/columnSelection/GridCellCheckboxRenderer.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { forwardRef } from '@mui/x-internals/forwardRef';
88
import { useGridApiContext } from '../../hooks/utils/useGridApiContext';
99
import { useGridRootProps } from '../../hooks/utils/useGridRootProps';
1010
import { getDataGridUtilityClass } from '../../constants/gridClasses';
11-
import { objectShallowCompare, useGridSelector } from '../../hooks/utils/useGridSelector';
12-
import { getCheckboxPropsSelector } from '../../hooks/features/rowSelection/utils';
11+
import { useGridSelector } from '../../hooks/utils/useGridSelector';
12+
import { checkboxPropsSelector } from '../../hooks/features/rowSelection/utils';
1313
import type { DataGridProcessedProps } from '../../models/props/DataGridProps';
1414
import type { GridRowSelectionCheckboxParams } from '../../models/params/gridRowSelectionCheckboxParams';
1515
import type { GridRenderCellParams } from '../../models/params/gridCellParams';
@@ -89,15 +89,10 @@ const GridCellCheckboxForwardRef = forwardRef<HTMLInputElement, GridRenderCellPa
8989

9090
const isSelectable = apiRef.current.isRowSelectable(id);
9191

92-
const checkboxPropsSelector = getCheckboxPropsSelector(
93-
id,
94-
rootProps.rowSelectionPropagation?.parents ?? false,
95-
);
96-
const { isIndeterminate, isChecked } = useGridSelector(
97-
apiRef,
98-
checkboxPropsSelector,
99-
objectShallowCompare,
100-
);
92+
const { isIndeterminate, isChecked } = useGridSelector(apiRef, checkboxPropsSelector, {
93+
groupId: id,
94+
autoSelectParents: rootProps.rowSelectionPropagation?.parents ?? false,
95+
});
10196

10297
if (rowNode.type === 'footer' || rowNode.type === 'pinnedRow') {
10398
return null;

packages/x-data-grid/src/hooks/features/rowSelection/utils.ts

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -50,57 +50,55 @@ function getGridRowGroupSelectableDescendants(
5050
return descendants;
5151
}
5252

53-
// TODO v8: Use `createSelectorV8`
54-
export function getCheckboxPropsSelector(groupId: GridRowId, autoSelectParents: boolean) {
55-
return createSelector(
56-
gridRowTreeSelector,
57-
gridSortedRowIdsSelector,
58-
gridFilteredRowsLookupSelector,
59-
selectedIdsLookupSelector,
60-
(rowTree, sortedRowIds, filteredRowsLookup, rowSelectionLookup) => {
61-
const groupNode = rowTree[groupId];
62-
if (!groupNode || groupNode.type !== 'group') {
63-
return {
64-
isIndeterminate: false,
65-
isChecked: rowSelectionLookup[groupId] === groupId,
66-
};
67-
}
53+
export const checkboxPropsSelector = createSelector(
54+
gridRowTreeSelector,
55+
gridFilteredRowsLookupSelector,
56+
gridRowSelectionManagerSelector,
57+
(
58+
rowTree,
59+
filteredRowsLookup,
60+
rowSelectionManager,
61+
{ groupId, autoSelectParents }: { groupId: GridRowId; autoSelectParents: boolean },
62+
) => {
63+
const groupNode = rowTree[groupId];
64+
if (!groupNode || groupNode.type !== 'group' || rowSelectionManager.has(groupId)) {
65+
return {
66+
isIndeterminate: false,
67+
isChecked: rowSelectionManager.has(groupId),
68+
};
69+
}
6870

69-
if (rowSelectionLookup[groupId] === groupId) {
70-
return {
71-
isIndeterminate: false,
72-
isChecked: true,
73-
};
74-
}
71+
let hasSelectedDescendant = false;
72+
let hasUnSelectedDescendant = false;
7573

76-
let selectableDescendantsCount = 0;
77-
let selectedDescendantsCount = 0;
78-
const startIndex = sortedRowIds.findIndex((id) => id === groupId) + 1;
79-
for (
80-
let index = startIndex;
81-
index < sortedRowIds.length && rowTree[sortedRowIds[index]]?.depth > groupNode.depth;
82-
index += 1
74+
const traverseDescendants = (itemToTraverseId: GridRowId) => {
75+
if (
76+
filteredRowsLookup[itemToTraverseId] === false ||
77+
// Perf: Skip checking the rest of the descendants if we already
78+
// know that there is a selected and an unselected descendant
79+
(hasSelectedDescendant && hasUnSelectedDescendant)
8380
) {
84-
const id = sortedRowIds[index];
85-
if (filteredRowsLookup[id] !== false) {
86-
selectableDescendantsCount += 1;
87-
if (rowSelectionLookup[id] !== undefined) {
88-
selectedDescendantsCount += 1;
89-
}
90-
}
81+
return;
9182
}
92-
return {
93-
isIndeterminate:
94-
selectedDescendantsCount > 0 &&
95-
(selectedDescendantsCount < selectableDescendantsCount ||
96-
rowSelectionLookup[groupId] === undefined),
97-
isChecked: autoSelectParents
98-
? selectedDescendantsCount > 0
99-
: rowSelectionLookup[groupId] === groupId,
100-
};
101-
},
102-
);
103-
}
83+
const node = rowTree[itemToTraverseId];
84+
if (node?.type === 'group') {
85+
node.children.forEach(traverseDescendants);
86+
}
87+
if (rowSelectionManager.has(itemToTraverseId)) {
88+
hasSelectedDescendant = true;
89+
} else {
90+
hasUnSelectedDescendant = true;
91+
}
92+
};
93+
94+
traverseDescendants(groupId);
95+
96+
return {
97+
isIndeterminate: hasSelectedDescendant && hasUnSelectedDescendant,
98+
isChecked: autoSelectParents ? hasSelectedDescendant && !hasUnSelectedDescendant : false,
99+
};
100+
},
101+
);
104102

105103
export function isMultipleRowSelectionEnabled(
106104
props: Pick<

0 commit comments

Comments
 (0)