@mui/x-data-grid
Version:
The Community plan edition of the MUI X Data Grid components.
596 lines (584 loc) • 27.7 kB
JavaScript
"use strict";
'use client';
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useGridRowSelection = exports.rowSelectionStateInitializer = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
var _signature = require("../../../constants/signature");
var _useGridEvent = require("../../utils/useGridEvent");
var _useGridApiMethod = require("../../utils/useGridApiMethod");
var _useGridLogger = require("../../utils/useGridLogger");
var _useGridSelector = require("../../utils/useGridSelector");
var _gridRowsSelector = require("../rows/gridRowsSelector");
var _gridRowSelectionSelector = require("./gridRowSelectionSelector");
var _gridFocusStateSelector = require("../focus/gridFocusStateSelector");
var _gridFilterSelector = require("../filter/gridFilterSelector");
var _colDef = require("../../../colDef");
var _gridEditRowModel = require("../../../models/gridEditRowModel");
var _keyboardUtils = require("../../../utils/keyboardUtils");
var _useGridVisibleRows = require("../../utils/useGridVisibleRows");
var _constants = require("../../../internals/constants");
var _gridClasses = require("../../../constants/gridClasses");
var _domUtils = require("../../../utils/domUtils");
var _utils = require("./utils");
var _gridRowSelectionManager = require("../../../models/gridRowSelectionManager");
var _pagination = require("../pagination");
const emptyModel = {
type: 'include',
ids: new Set()
};
const rowSelectionStateInitializer = (state, props) => (0, _extends2.default)({}, state, {
rowSelection: props.rowSelection ? props.rowSelectionModel ?? emptyModel : emptyModel
});
/**
* @requires useGridRows (state, method) - can be after
* @requires useGridParamsApi (method) - can be after
* @requires useGridFocus (state) - can be after
* @requires useGridKeyboardNavigation (`cellKeyDown` event must first be consumed by it)
*/
exports.rowSelectionStateInitializer = rowSelectionStateInitializer;
const useGridRowSelection = (apiRef, props) => {
const logger = (0, _useGridLogger.useGridLogger)(apiRef, 'useGridSelection');
const runIfRowSelectionIsEnabled = React.useCallback(callback => (...args) => {
if (props.rowSelection) {
callback(...args);
}
}, [props.rowSelection]);
const applyAutoSelection = props.signature !== _signature.GridSignature.DataGrid && (props.rowSelectionPropagation?.parents || props.rowSelectionPropagation?.descendants);
const propRowSelectionModel = React.useMemo(() => {
return props.rowSelectionModel;
}, [props.rowSelectionModel]);
const lastRowToggled = React.useRef(null);
apiRef.current.registerControlState({
stateId: 'rowSelection',
propModel: propRowSelectionModel,
propOnChange: props.onRowSelectionModelChange,
stateSelector: _gridRowSelectionSelector.gridRowSelectionStateSelector,
changeEvent: 'rowSelectionChange'
});
const {
checkboxSelection,
disableRowSelectionOnClick,
isRowSelectable: propIsRowSelectable
} = props;
const canHaveMultipleSelection = (0, _utils.isMultipleRowSelectionEnabled)(props);
const tree = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsSelector.gridRowTreeSelector);
const isNestedData = (0, _useGridSelector.useGridSelector)(apiRef, _gridRowsSelector.gridRowMaximumTreeDepthSelector) > 1;
const expandMouseRowRangeSelection = React.useCallback(id => {
let endId = id;
const startId = lastRowToggled.current ?? id;
const isSelected = apiRef.current.isRowSelected(id);
if (isSelected) {
const visibleRowIds = (0, _gridFilterSelector.gridExpandedSortedRowIdsSelector)(apiRef);
const startIndex = visibleRowIds.findIndex(rowId => rowId === startId);
const endIndex = visibleRowIds.findIndex(rowId => rowId === endId);
if (startIndex === endIndex) {
return;
}
if (startIndex > endIndex) {
endId = visibleRowIds[endIndex + 1];
} else {
endId = visibleRowIds[endIndex - 1];
}
}
lastRowToggled.current = id;
apiRef.current.selectRowRange({
startId,
endId
}, !isSelected);
}, [apiRef]);
const getRowsToBeSelected = (0, _useEventCallback.default)(() => {
const rowsToBeSelected = props.pagination && props.checkboxSelectionVisibleOnly && props.paginationMode === 'client' ? (0, _pagination.gridPaginatedVisibleSortedGridRowIdsSelector)(apiRef) : (0, _gridFilterSelector.gridExpandedSortedRowIdsSelector)(apiRef);
return rowsToBeSelected;
});
/*
* API METHODS
*/
const setRowSelectionModel = React.useCallback((model, reason) => {
if (props.signature === _signature.GridSignature.DataGrid && !canHaveMultipleSelection && (model.type !== 'include' || model.ids.size > 1)) {
throw new Error(['MUI X: `rowSelectionModel` can only contain 1 item in DataGrid.', 'You need to upgrade to DataGridPro or DataGridPremium component to unlock multiple selection.'].join('\n'));
}
const currentModel = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
if (currentModel !== model) {
logger.debug(`Setting selection model`);
apiRef.current.setState(state => (0, _extends2.default)({}, state, {
rowSelection: props.rowSelection ? model : emptyModel
}), reason);
}
}, [apiRef, logger, props.rowSelection, props.signature, canHaveMultipleSelection]);
const isRowSelected = React.useCallback(id => {
const selectionManager = (0, _gridRowSelectionSelector.gridRowSelectionManagerSelector)(apiRef);
return selectionManager.has(id);
}, [apiRef]);
const isRowSelectable = React.useCallback(id => {
if (props.rowSelection === false) {
return false;
}
if (propIsRowSelectable && !propIsRowSelectable(apiRef.current.getRowParams(id))) {
return false;
}
const rowNode = (0, _gridRowsSelector.gridRowNodeSelector)(apiRef, id);
if (rowNode?.type === 'footer' || rowNode?.type === 'pinnedRow') {
return false;
}
return true;
}, [apiRef, props.rowSelection, propIsRowSelectable]);
const getSelectedRows = React.useCallback(() => (0, _gridRowSelectionSelector.gridRowSelectionIdsSelector)(apiRef), [apiRef]);
const selectRow = React.useCallback((id, isSelected = true, resetSelection = false) => {
if (!apiRef.current.isRowSelectable(id)) {
return;
}
lastRowToggled.current = id;
if (resetSelection) {
logger.debug(`Setting selection for row ${id}`);
const newSelectionModel = {
type: 'include',
ids: new Set()
};
const addRow = rowId => {
newSelectionModel.ids.add(rowId);
};
if (isSelected) {
addRow(id);
if (applyAutoSelection) {
(0, _utils.findRowsToSelect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow);
}
}
apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
} else {
logger.debug(`Toggling selection for row ${id}`);
const selectionModel = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
const newSelectionModel = {
type: selectionModel.type,
ids: new Set(selectionModel.ids)
};
const selectionManager = (0, _gridRowSelectionManager.createRowSelectionManager)(newSelectionModel);
selectionManager.unselect(id);
const addRow = rowId => {
selectionManager.select(rowId);
};
const removeRow = rowId => {
selectionManager.unselect(rowId);
};
if (isSelected) {
addRow(id);
if (applyAutoSelection) {
(0, _utils.findRowsToSelect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow);
}
} else if (applyAutoSelection) {
(0, _utils.findRowsToDeselect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, removeRow);
}
const isSelectionValid = newSelectionModel.type === 'include' && newSelectionModel.ids.size < 2 || canHaveMultipleSelection;
if (isSelectionValid) {
apiRef.current.setRowSelectionModel(newSelectionModel, 'singleRowSelection');
}
}
}, [apiRef, logger, applyAutoSelection, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, canHaveMultipleSelection]);
const selectRows = React.useCallback((ids, isSelected = true, resetSelection = false) => {
logger.debug(`Setting selection for several rows`);
if (props.rowSelection === false) {
return;
}
const selectableIds = new Set();
for (let i = 0; i < ids.length; i += 1) {
const id = ids[i];
if (apiRef.current.isRowSelectable(id)) {
selectableIds.add(id);
}
}
const currentSelectionModel = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
let newSelectionModel;
if (resetSelection) {
newSelectionModel = {
type: 'include',
ids: selectableIds
};
if (isSelected) {
const selectionManager = (0, _gridRowSelectionManager.createRowSelectionManager)(newSelectionModel);
if (applyAutoSelection) {
const addRow = rowId => {
selectionManager.select(rowId);
};
for (const id of selectableIds) {
(0, _utils.findRowsToSelect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow);
}
}
} else {
newSelectionModel.ids = new Set();
}
if (currentSelectionModel.type === newSelectionModel.type && newSelectionModel.ids.size === currentSelectionModel.ids.size && Array.from(newSelectionModel.ids).every(id => currentSelectionModel.ids.has(id))) {
return;
}
} else {
newSelectionModel = {
type: currentSelectionModel.type,
ids: new Set(currentSelectionModel.ids)
};
const selectionManager = (0, _gridRowSelectionManager.createRowSelectionManager)(newSelectionModel);
const addRow = rowId => {
selectionManager.select(rowId);
};
const removeRow = rowId => {
selectionManager.unselect(rowId);
};
for (const id of selectableIds) {
if (isSelected) {
selectionManager.select(id);
if (applyAutoSelection) {
(0, _utils.findRowsToSelect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow);
}
} else {
removeRow(id);
if (applyAutoSelection) {
(0, _utils.findRowsToDeselect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, removeRow);
}
}
}
}
const isSelectionValid = newSelectionModel.type === 'include' && newSelectionModel.ids.size < 2 || canHaveMultipleSelection;
if (isSelectionValid) {
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
}
}, [logger, applyAutoSelection, canHaveMultipleSelection, apiRef, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, props.rowSelection]);
const getPropagatedRowSelectionModel = React.useCallback(inputSelectionModel => {
if (!isNestedData || !applyAutoSelection || inputSelectionModel.ids.size === 0 && inputSelectionModel.type === 'include') {
return inputSelectionModel;
}
const propagatedSelectionModel = {
type: inputSelectionModel.type,
ids: new Set(inputSelectionModel.ids)
};
const selectionManager = (0, _gridRowSelectionManager.createRowSelectionManager)(propagatedSelectionModel);
const addRow = rowId => {
selectionManager.select(rowId);
};
for (const id of inputSelectionModel.ids) {
(0, _utils.findRowsToSelect)(apiRef, tree, id, props.rowSelectionPropagation?.descendants ?? false, props.rowSelectionPropagation?.parents ?? false, addRow, selectionManager);
}
return propagatedSelectionModel;
}, [apiRef, tree, props.rowSelectionPropagation?.descendants, props.rowSelectionPropagation?.parents, isNestedData, applyAutoSelection]);
const selectRowRange = React.useCallback(({
startId,
endId
}, isSelected = true, resetSelection = false) => {
if (!apiRef.current.getRow(startId) || !apiRef.current.getRow(endId)) {
return;
}
logger.debug(`Expanding selection from row ${startId} to row ${endId}`);
// Using rows from all pages allow to select a range across several pages
const allPagesRowIds = (0, _gridFilterSelector.gridExpandedSortedRowIdsSelector)(apiRef);
const startIndex = allPagesRowIds.indexOf(startId);
const endIndex = allPagesRowIds.indexOf(endId);
const [start, end] = startIndex > endIndex ? [endIndex, startIndex] : [startIndex, endIndex];
const rowsBetweenStartAndEnd = allPagesRowIds.slice(start, end + 1);
apiRef.current.selectRows(rowsBetweenStartAndEnd, isSelected, resetSelection);
}, [apiRef, logger]);
const selectionPublicApi = {
selectRow,
setRowSelectionModel,
getSelectedRows,
isRowSelected,
isRowSelectable
};
const selectionPrivateApi = {
selectRows,
selectRowRange,
getPropagatedRowSelectionModel
};
(0, _useGridApiMethod.useGridApiMethod)(apiRef, selectionPublicApi, 'public');
(0, _useGridApiMethod.useGridApiMethod)(apiRef, selectionPrivateApi, props.signature === _signature.GridSignature.DataGrid ? 'private' : 'public');
/*
* EVENTS
*/
const isFirstRender = React.useRef(true);
const removeOutdatedSelection = React.useCallback((sortModelUpdated = false) => {
if (isFirstRender.current) {
return;
}
const currentSelection = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
const rowsLookup = (0, _gridRowsSelector.gridRowsLookupSelector)(apiRef);
const rowTree = (0, _gridRowsSelector.gridRowTreeSelector)(apiRef);
const filteredRowsLookup = (0, _gridFilterSelector.gridFilteredRowsLookupSelector)(apiRef);
const isNonExistent = id => {
if (props.filterMode === 'server') {
return !rowsLookup[id];
}
return !rowTree[id] || filteredRowsLookup[id] === false;
};
const newSelectionModel = {
type: currentSelection.type,
ids: new Set(currentSelection.ids)
};
const selectionManager = (0, _gridRowSelectionManager.createRowSelectionManager)(newSelectionModel);
let hasChanged = false;
for (const id of currentSelection.ids) {
if (isNonExistent(id)) {
if (props.keepNonExistentRowsSelected) {
continue;
}
selectionManager.unselect(id);
hasChanged = true;
continue;
}
if (!props.rowSelectionPropagation?.parents) {
continue;
}
const node = tree[id];
if (node?.type === 'group') {
const isAutoGenerated = node.isAutoGenerated;
if (isAutoGenerated) {
selectionManager.unselect(id);
hasChanged = true;
continue;
}
// Keep previously selected tree data parents selected if all their children are filtered out
if (!node.children.every(childId => filteredRowsLookup[childId] === false)) {
selectionManager.unselect(id);
hasChanged = true;
}
}
}
// For nested data, on row tree updation (filtering, adding rows, etc.) when the selection is
// not empty, we need to re-run scanning of the tree to propagate the selection changes
// Example: A parent whose de-selected children are filtered out should now be selected
const shouldReapplyPropagation = isNestedData && props.rowSelectionPropagation?.parents && (newSelectionModel.ids.size > 0 ||
// In case of exclude selection, newSelectionModel.ids.size === 0 means all rows are selected
newSelectionModel.type === 'exclude');
if (hasChanged || shouldReapplyPropagation && !sortModelUpdated) {
if (shouldReapplyPropagation) {
if (newSelectionModel.type === 'exclude') {
const unfilteredSelectedRowIds = getRowsToBeSelected();
const selectedRowIds = [];
for (let i = 0; i < unfilteredSelectedRowIds.length; i += 1) {
const rowId = unfilteredSelectedRowIds[i];
if ((props.keepNonExistentRowsSelected || !isNonExistent(rowId)) && selectionManager.has(rowId)) {
selectedRowIds.push(rowId);
}
}
apiRef.current.selectRows(selectedRowIds, true, true);
} else {
apiRef.current.selectRows(Array.from(newSelectionModel.ids), true, true);
}
} else {
apiRef.current.setRowSelectionModel(newSelectionModel, 'multipleRowsSelection');
}
}
}, [apiRef, isNestedData, props.rowSelectionPropagation?.parents, props.keepNonExistentRowsSelected, props.filterMode, tree, getRowsToBeSelected]);
const handleSingleRowSelection = React.useCallback((id, event) => {
const hasCtrlKey = event.metaKey || event.ctrlKey;
// multiple selection is only allowed if:
// - it is a checkboxSelection
// - it is a keyboard selection
// - Ctrl is pressed
const isMultipleSelectionDisabled = !checkboxSelection && !hasCtrlKey && !(0, _keyboardUtils.isKeyboardEvent)(event);
const resetSelection = !canHaveMultipleSelection || isMultipleSelectionDisabled;
const isSelected = apiRef.current.isRowSelected(id);
const selectedRowsCount = (0, _gridRowSelectionSelector.gridRowSelectionCountSelector)(apiRef);
// Clicking on a row should toggle the selection except when a range of rows is already selected and the selection should reset
// In that case, we want to keep the current row selected (https://github.com/mui/mui-x/pull/15509#discussion_r1878082687)
const shouldStaySelected = selectedRowsCount > 1 && resetSelection;
const newSelectionState = shouldStaySelected || !isSelected;
apiRef.current.selectRow(id, newSelectionState, resetSelection);
}, [apiRef, canHaveMultipleSelection, checkboxSelection]);
const handleRowClick = React.useCallback((params, event) => {
if (disableRowSelectionOnClick) {
return;
}
const field = event.target.closest(`.${_gridClasses.gridClasses.cell}`)?.getAttribute('data-field');
if (field === _colDef.GRID_CHECKBOX_SELECTION_COL_DEF.field) {
// click on checkbox should not trigger row selection
return;
}
if (field === _constants.GRID_DETAIL_PANEL_TOGGLE_FIELD) {
// click to open the detail panel should not select the row
return;
}
if (field) {
const column = apiRef.current.getColumn(field);
if (column?.type === _colDef.GRID_ACTIONS_COLUMN_TYPE) {
return;
}
}
const rowNode = (0, _gridRowsSelector.gridRowNodeSelector)(apiRef, params.id);
if (rowNode.type === 'pinnedRow') {
return;
}
if (event.shiftKey && canHaveMultipleSelection) {
expandMouseRowRangeSelection(params.id);
} else {
handleSingleRowSelection(params.id, event);
}
}, [disableRowSelectionOnClick, canHaveMultipleSelection, apiRef, expandMouseRowRangeSelection, handleSingleRowSelection]);
const preventSelectionOnShift = React.useCallback((params, event) => {
if (canHaveMultipleSelection && event.shiftKey) {
window.getSelection()?.removeAllRanges();
}
}, [canHaveMultipleSelection]);
const handleRowSelectionCheckboxChange = React.useCallback((params, event) => {
if (canHaveMultipleSelection && event.nativeEvent.shiftKey) {
expandMouseRowRangeSelection(params.id);
} else {
apiRef.current.selectRow(params.id, params.value, !canHaveMultipleSelection);
}
}, [apiRef, expandMouseRowRangeSelection, canHaveMultipleSelection]);
const toggleAllRows = React.useCallback(value => {
const filterModel = (0, _gridFilterSelector.gridFilterModelSelector)(apiRef);
const quickFilterModel = (0, _gridFilterSelector.gridQuickFilterValuesSelector)(apiRef);
const hasFilters = filterModel.items.length > 0 || quickFilterModel?.some(val => val.length);
if (!props.isRowSelectable && !props.checkboxSelectionVisibleOnly && (!isNestedData || props.rowSelectionPropagation?.descendants) && !hasFilters) {
apiRef.current.setRowSelectionModel({
type: value ? 'exclude' : 'include',
ids: new Set()
}, 'multipleRowsSelection');
} else {
apiRef.current.selectRows(getRowsToBeSelected(), value);
}
}, [apiRef, getRowsToBeSelected, props.checkboxSelectionVisibleOnly, props.isRowSelectable, props.rowSelectionPropagation?.descendants, isNestedData]);
const handleHeaderSelectionCheckboxChange = React.useCallback(params => {
toggleAllRows(params.value);
}, [toggleAllRows]);
const handleCellKeyDown = React.useCallback((params, event) => {
// Get the most recent cell mode because it may have been changed by another listener
if (apiRef.current.getCellMode(params.id, params.field) === _gridEditRowModel.GridCellModes.Edit) {
return;
}
// Ignore portal
// Do not apply shortcuts if the focus is not on the cell root component
if ((0, _domUtils.isEventTargetInPortal)(event)) {
return;
}
if ((0, _keyboardUtils.isNavigationKey)(event.key) && event.shiftKey) {
// The cell that has focus after the keyboard navigation
const focusCell = (0, _gridFocusStateSelector.gridFocusCellSelector)(apiRef);
if (focusCell && focusCell.id !== params.id) {
event.preventDefault();
const isNextRowSelected = apiRef.current.isRowSelected(focusCell.id);
if (!canHaveMultipleSelection) {
apiRef.current.selectRow(focusCell.id, !isNextRowSelected, true);
return;
}
const newRowIndex = apiRef.current.getRowIndexRelativeToVisibleRows(focusCell.id);
const previousRowIndex = apiRef.current.getRowIndexRelativeToVisibleRows(params.id);
let start;
let end;
if (newRowIndex > previousRowIndex) {
if (isNextRowSelected) {
// We are navigating to the bottom of the page and adding selected rows
start = previousRowIndex;
end = newRowIndex - 1;
} else {
// We are navigating to the bottom of the page and removing selected rows
start = previousRowIndex;
end = newRowIndex;
}
} else {
// eslint-disable-next-line no-lonely-if
if (isNextRowSelected) {
// We are navigating to the top of the page and removing selected rows
start = newRowIndex + 1;
end = previousRowIndex;
} else {
// We are navigating to the top of the page and adding selected rows
start = newRowIndex;
end = previousRowIndex;
}
}
const visibleRows = (0, _useGridVisibleRows.getVisibleRows)(apiRef);
const rowsBetweenStartAndEnd = [];
for (let i = start; i <= end; i += 1) {
rowsBetweenStartAndEnd.push(visibleRows.rows[i].id);
}
apiRef.current.selectRows(rowsBetweenStartAndEnd, !isNextRowSelected);
return;
}
}
if (event.key === ' ' && event.shiftKey) {
event.preventDefault();
handleSingleRowSelection(params.id, event);
return;
}
if (String.fromCharCode(event.keyCode) === 'A' && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
toggleAllRows(true);
}
}, [apiRef, canHaveMultipleSelection, handleSingleRowSelection, toggleAllRows]);
const syncControlledState = (0, _useEventCallback.default)(() => {
if (!props.rowSelection) {
apiRef.current.setRowSelectionModel(emptyModel);
return;
}
if (propRowSelectionModel === undefined) {
return;
}
if (!applyAutoSelection || !isNestedData || propRowSelectionModel.type === 'include' && propRowSelectionModel.ids.size === 0) {
apiRef.current.setRowSelectionModel(propRowSelectionModel);
return;
}
const newSelectionModel = apiRef.current.getPropagatedRowSelectionModel(propRowSelectionModel);
if (newSelectionModel.type !== propRowSelectionModel.type || newSelectionModel.ids.size !== propRowSelectionModel.ids.size || !Array.from(propRowSelectionModel.ids).every(id => newSelectionModel.ids.has(id))) {
apiRef.current.setRowSelectionModel(newSelectionModel);
return;
}
apiRef.current.setRowSelectionModel(propRowSelectionModel);
});
(0, _useGridEvent.useGridEvent)(apiRef, 'sortedRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection(true)));
(0, _useGridEvent.useGridEvent)(apiRef, 'filteredRowsSet', runIfRowSelectionIsEnabled(() => removeOutdatedSelection()));
(0, _useGridEvent.useGridEvent)(apiRef, 'rowClick', runIfRowSelectionIsEnabled(handleRowClick));
(0, _useGridEvent.useGridEvent)(apiRef, 'rowSelectionCheckboxChange', runIfRowSelectionIsEnabled(handleRowSelectionCheckboxChange));
(0, _useGridEvent.useGridEvent)(apiRef, 'headerSelectionCheckboxChange', handleHeaderSelectionCheckboxChange);
(0, _useGridEvent.useGridEvent)(apiRef, 'cellMouseDown', runIfRowSelectionIsEnabled(preventSelectionOnShift));
(0, _useGridEvent.useGridEvent)(apiRef, 'cellKeyDown', runIfRowSelectionIsEnabled(handleCellKeyDown));
/*
* EFFECTS
*/
React.useEffect(() => {
syncControlledState();
}, [apiRef, propRowSelectionModel, props.rowSelection, syncControlledState]);
const isStateControlled = propRowSelectionModel != null;
React.useEffect(() => {
if (isStateControlled || !props.rowSelection || typeof isRowSelectable !== 'function') {
return;
}
// props.isRowSelectable changed
const currentSelection = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
if (currentSelection.type !== 'include') {
return;
}
const selectableIds = new Set();
for (const id of currentSelection.ids) {
if (isRowSelectable(id)) {
selectableIds.add(id);
}
}
if (selectableIds.size < currentSelection.ids.size) {
apiRef.current.setRowSelectionModel({
type: currentSelection.type,
ids: selectableIds
});
}
}, [apiRef, isRowSelectable, isStateControlled, props.rowSelection]);
React.useEffect(() => {
if (!props.rowSelection || isStateControlled) {
return;
}
const currentSelection = (0, _gridRowSelectionSelector.gridRowSelectionStateSelector)(apiRef);
if (!canHaveMultipleSelection && (currentSelection.type === 'include' && currentSelection.ids.size > 1 || currentSelection.type === 'exclude')) {
// See https://github.com/mui/mui-x/issues/8455
apiRef.current.setRowSelectionModel(emptyModel);
}
}, [apiRef, canHaveMultipleSelection, checkboxSelection, isStateControlled, props.rowSelection]);
React.useEffect(() => {
runIfRowSelectionIsEnabled(removeOutdatedSelection);
}, [removeOutdatedSelection, runIfRowSelectionIsEnabled]);
React.useEffect(() => {
if (isFirstRender.current) {
isFirstRender.current = false;
}
}, []);
};
exports.useGridRowSelection = useGridRowSelection;