Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DataGrid] Make checkboxSelection respect the disableMultipleRowSelection prop #11448

Merged
merged 13 commits into from
Dec 22, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ describe('<DataGridPro /> - Row selection', () => {
fireEvent.click(screen.getByRole('button', { name: /next page/i }));
expect(selectAllCheckbox).to.have.attr('data-indeterminate', 'true');
});

it('should not select more than one row when disableMultipleRowSelection = true', () => {
render(<TestDataGridSelection checkboxSelection disableMultipleRowSelection />);
const input1 = getCell(0, 0).querySelector('input')!;
fireEvent.click(input1);
expect(input1.checked).to.equal(true);

const input2 = getCell(1, 0).querySelector('input')!;
fireEvent.click(input2);
expect(input1.checked).to.equal(false);
expect(input2.checked).to.equal(true);
});
});

describe('prop: checkboxSelectionVisibleOnly = true', () => {
Expand Down
1 change: 0 additions & 1 deletion packages/grid/x-data-grid/src/DataGrid/useDataGridProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { computeSlots, useProps } from '../internals/utils';
const DATA_GRID_FORCED_PROPS: { [key in DataGridForcedPropsKey]?: DataGridProcessedProps[key] } = {
disableMultipleColumnsFiltering: true,
disableMultipleColumnsSorting: true,
disableMultipleRowSelection: true,
throttleRowsMs: undefined,
hideFooterRowCount: false,
pagination: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { unstable_composeClasses as composeClasses } from '@mui/utils';
import { isMultipleRowSelectionEnabled } from '../../hooks/features/rowSelection/utils';
import { useGridSelector } from '../../hooks/utils/useGridSelector';
import { gridTabIndexColumnHeaderSelector } from '../../hooks/features/focus/gridFocusStateSelector';
import { gridRowSelectionStateSelector } from '../../hooks/features/rowSelection/gridRowSelectionSelector';
Expand Down Expand Up @@ -138,6 +139,7 @@ const GridHeaderCheckbox = React.forwardRef<HTMLInputElement, GridColumnHeaderPa
inputProps={{ 'aria-label': label }}
tabIndex={tabIndex}
onKeyDown={handleKeyDown}
disabled={!isMultipleRowSelectionEnabled(rootProps)}
{...rootProps.slotProps?.baseCheckbox}
{...other}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { GridRowSelectionModel } from '../../../models';
import { GRID_DETAIL_PANEL_TOGGLE_FIELD } from '../../../constants/gridDetailPanelToggleField';
import { gridClasses } from '../../../constants/gridClasses';
import { isEventTargetInPortal } from '../../../utils/domUtils';
import { isMultipleRowSelectionEnabled } from './utils';

const getSelectionModelPropValue = (
selectionModelProp: DataGridProcessedProps['rowSelectionModel'],
Expand Down Expand Up @@ -109,12 +110,11 @@ export const useGridRowSelection = (

const {
checkboxSelection,
disableMultipleRowSelection,
disableRowSelectionOnClick,
isRowSelectable: propIsRowSelectable,
} = props;

const canHaveMultipleSelection = !disableMultipleRowSelection || checkboxSelection;
const canHaveMultipleSelection = isMultipleRowSelectionEnabled(props);
const visibleRows = useGridVisibleRows(apiRef, props);

const expandMouseRowRangeSelection = React.useCallback(
Expand Down Expand Up @@ -150,7 +150,7 @@ export const useGridRowSelection = (
(model) => {
if (
props.signature === GridSignature.DataGrid &&
!props.checkboxSelection &&
!canHaveMultipleSelection &&
Array.isArray(model) &&
model.length > 1
) {
Expand All @@ -171,7 +171,7 @@ export const useGridRowSelection = (
apiRef.current.forceUpdate();
}
},
[apiRef, logger, props.rowSelection, props.signature, props.checkboxSelection],
[apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection],
);

const isRowSelected = React.useCallback<GridRowSelectionApi['isRowSelected']>(
Expand Down Expand Up @@ -397,7 +397,7 @@ export const useGridRowSelection = (
return;
}

if (event.shiftKey && (canHaveMultipleSelection || checkboxSelection)) {
if (event.shiftKey && canHaveMultipleSelection) {
expandMouseRowRangeSelection(params.id);
} else {
handleSingleRowSelection(params.id, event);
Expand All @@ -406,7 +406,6 @@ export const useGridRowSelection = (
[
disableRowSelectionOnClick,
canHaveMultipleSelection,
checkboxSelection,
apiRef,
expandMouseRowRangeSelection,
handleSingleRowSelection,
Expand All @@ -426,13 +425,13 @@ export const useGridRowSelection = (
GridEventListener<'rowSelectionCheckboxChange'>
>(
(params, event) => {
if ((event.nativeEvent as any).shiftKey) {
if (canHaveMultipleSelection && (event.nativeEvent as any).shiftKey) {
expandMouseRowRangeSelection(params.id);
} else {
apiRef.current.selectRow(params.id, params.value);
apiRef.current.selectRow(params.id, params.value, !canHaveMultipleSelection);
}
},
[apiRef, expandMouseRowRangeSelection],
[apiRef, expandMouseRowRangeSelection, canHaveMultipleSelection],
);

const handleHeaderSelectionCheckboxChange = React.useCallback<
Expand Down
15 changes: 15 additions & 0 deletions packages/grid/x-data-grid/src/hooks/features/rowSelection/utils.ts
MBilalShafi marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { DataGridProcessedProps } from '../../../models/props/DataGridProps';
import { GridSignature } from '../../utils/useGridApiEventHandler';

export function isMultipleRowSelectionEnabled(
props: Pick<
DataGridProcessedProps,
'signature' | 'disableMultipleRowSelection' | 'checkboxSelection'
>,
) {
if (props.signature === GridSignature.DataGrid) {
// DataGrid Community has multiple row selection enabled only if checkbox selection is enabled.
return props.checkboxSelection && props.disableMultipleRowSelection !== true;
}
return !props.disableMultipleRowSelection;
}
Comment on lines +10 to +15
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit messy, but the main change in this PR is that you can now pass the disableMultipleRowSelection prop to MIT DataGrid.
The default behavior hasn't changed, so this PR does not bring any breaking changes.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
gridRowCountSelector,
} from '../features/rows/gridRowsSelector';
import { useGridPrivateApiContext } from './useGridPrivateApiContext';
import { isMultipleRowSelectionEnabled } from '../features/rowSelection/utils';

export const useGridAriaAttributes = () => {
const apiRef = useGridPrivateApiContext();
Expand All @@ -25,6 +26,6 @@ export const useGridAriaAttributes = () => {
role,
'aria-colcount': visibleColumns.length,
'aria-rowcount': headerGroupingMaxDepth + 1 + pinnedRowsCount + totalRowCount,
'aria-multiselectable': !rootProps.disableMultipleRowSelection,
'aria-multiselectable': isMultipleRowSelectionEnabled(rootProps),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export type DataGridForcedPropsKey =
| 'checkboxSelectionVisibleOnly'
| 'disableMultipleColumnsFiltering'
| 'disableMultipleColumnsSorting'
| 'disableMultipleRowSelection'
| 'disableColumnReorder'
| 'disableColumnResize'
| 'keepColumnPositionIfDraggedOutside'
Expand Down
12 changes: 12 additions & 0 deletions packages/grid/x-data-grid/src/tests/rowSelection.DataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,18 @@ describe('<DataGrid /> - Row selection', () => {
expect(screen.queryByRole('checkbox', { name: 'Select row' })).to.equal(null);
expect(screen.queryByRole('checkbox', { name: 'Unselect row' })).not.to.equal(null);
});

it('should not select more than one row when disableMultipleRowSelection = true', () => {
render(<TestDataGridSelection checkboxSelection disableMultipleRowSelection />);
const input1 = getCell(0, 0).querySelector('input')!;
fireEvent.click(input1);
expect(input1.checked).to.equal(true);

const input2 = getCell(1, 0).querySelector('input')!;
fireEvent.click(input2);
expect(input1.checked).to.equal(false);
expect(input2.checked).to.equal(true);
});
});

describe('prop: checkboxSelection = true (multi selection), with keyboard events', () => {
Expand Down
Loading