UNPKG

@mui/x-data-grid

Version:

The community edition of the data grid component (MUI X).

183 lines (162 loc) 7.08 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _extends from "@babel/runtime/helpers/esm/extends"; import * as React from 'react'; import { GridCellModes } from '../../../models/gridEditRowModel'; import { useGridApiEventHandler, useGridApiOptionHandler } from '../../utils/useGridApiEventHandler'; import { useGridApiMethod } from '../../utils/useGridApiMethod'; import { useGridLogger } from '../../utils/useGridLogger'; import { gridEditRowsStateSelector } from './gridEditRowsSelector'; import { useCellEditing } from './useGridCellEditing.old'; import { useGridRowEditing } from './useGridRowEditing.old'; export var editingStateInitializer = function editingStateInitializer(state) { return _extends({}, state, { editRows: {} }); }; /** * @requires useGridFocus - can be after, async only * @requires useGridParamsApi (method) * @requires useGridColumns (state) */ export function useGridEditing(apiRef, props) { var _props$experimentalFe2; var logger = useGridLogger(apiRef, 'useGridEditRows'); useCellEditing(apiRef, props); useGridRowEditing(apiRef, props); var debounceMap = React.useRef({}); apiRef.current.unstable_registerControlState({ stateId: 'editRows', propModel: props.editRowsModel, propOnChange: props.onEditRowsModelChange, stateSelector: gridEditRowsStateSelector, changeEvent: 'editRowsModelChange' }); var isCellEditable = React.useCallback(function (params) { return !params.rowNode.isAutoGenerated && !params.rowNode.isPinned && !!params.colDef.editable && !!params.colDef.renderEditCell && (!props.isCellEditable || props.isCellEditable(params)); }, // eslint-disable-next-line react-hooks/exhaustive-deps [props.isCellEditable]); var maybeDebounce = function maybeDebounce(id, field, debounceMs, callback) { if (!debounceMs) { callback(); return; } if (!debounceMap.current[id]) { debounceMap.current[id] = {}; } if (debounceMap.current[id][field]) { var _debounceMap$current$ = _slicedToArray(debounceMap.current[id][field], 1), _timeout = _debounceMap$current$[0]; clearTimeout(_timeout); } var callbackToRunImmediately = function callbackToRunImmediately() { callback(); var _debounceMap$current$2 = _slicedToArray(debounceMap.current[id][field], 1), timeout = _debounceMap$current$2[0]; clearTimeout(timeout); delete debounceMap.current[id][field]; }; var timeout = setTimeout(function () { callback(); delete debounceMap.current[id][field]; }, debounceMs); debounceMap.current[id][field] = [timeout, callbackToRunImmediately]; }; var runPendingEditCellValueMutation = React.useCallback(function (id, field) { if (!debounceMap.current[id]) { return; } if (!field) { Object.keys(debounceMap.current[id]).forEach(function (debouncedField) { var _debounceMap$current$3 = _slicedToArray(debounceMap.current[id][debouncedField], 2), callback = _debounceMap$current$3[1]; callback(); }); } else if (debounceMap.current[id][field]) { var _debounceMap$current$4 = _slicedToArray(debounceMap.current[id][field], 2), callback = _debounceMap$current$4[1]; callback(); } }, []); var setEditCellValue = React.useCallback(function (params) { var event = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; maybeDebounce(params.id, params.field, params.debounceMs, function () { var _props$experimentalFe; if ((_props$experimentalFe = props.experimentalFeatures) != null && _props$experimentalFe.preventCommitWhileValidating) { if (props.editMode === 'row') { return apiRef.current.unstable_setRowEditingEditCellValue(params); } return apiRef.current.unstable_setCellEditingEditCellValue(params); } var newParams = { id: params.id, field: params.field, props: { value: params.value } }; return apiRef.current.publishEvent('editCellPropsChange', newParams, event); }); }, [apiRef, props.editMode, (_props$experimentalFe2 = props.experimentalFeatures) == null ? void 0 : _props$experimentalFe2.preventCommitWhileValidating]); var parseValue = React.useCallback(function (id, field, value) { var column = apiRef.current.getColumn(field); return column.valueParser ? column.valueParser(value, apiRef.current.getCellParams(id, field)) : value; }, [apiRef]); var setEditCellProps = React.useCallback(function (params) { var id = params.id, field = params.field, editProps = params.props; logger.debug("Setting cell props on id: ".concat(id, " field: ").concat(field)); apiRef.current.setState(function (state) { var editRowsModel = _extends({}, state.editRows); editRowsModel[id] = _extends({}, state.editRows[id]); editRowsModel[id][field] = _extends({}, editProps, { value: parseValue(id, field, editProps.value) }); return _extends({}, state, { editRows: editRowsModel }); }); apiRef.current.forceUpdate(); var editRowsState = gridEditRowsStateSelector(apiRef.current.state); return editRowsState[id][field]; }, [apiRef, logger, parseValue]); var setEditRowsModel = React.useCallback(function (model) { var currentModel = gridEditRowsStateSelector(apiRef.current.state); if (currentModel !== model) { logger.debug("Setting editRows model"); apiRef.current.setState(function (state) { return _extends({}, state, { editRows: model }); }); apiRef.current.forceUpdate(); } }, [apiRef, logger]); var getEditRowsModel = React.useCallback(function () { return gridEditRowsStateSelector(apiRef.current.state); }, [apiRef]); var preventTextSelection = React.useCallback(function (params, event) { var isMoreThanOneClick = event.detail > 1; if (params.isEditable && params.cellMode === GridCellModes.View && isMoreThanOneClick) { // If we click more than one time, then we prevent the default behavior of selecting the text cell. event.preventDefault(); } }, []); useGridApiEventHandler(apiRef, 'cellMouseDown', preventTextSelection); useGridApiOptionHandler(apiRef, 'editCellPropsChange', props.onEditCellPropsChange); // TODO v6: remove, use `preProcessEditCellProps` instead var editingSharedApi = { isCellEditable: isCellEditable, setEditRowsModel: setEditRowsModel, getEditRowsModel: getEditRowsModel, setEditCellValue: setEditCellValue, unstable_setEditCellProps: setEditCellProps, unstable_parseValue: parseValue, unstable_runPendingEditCellValueMutation: runPendingEditCellValueMutation }; useGridApiMethod(apiRef, editingSharedApi, 'EditRowApi'); React.useEffect(function () { if (props.editRowsModel !== undefined) { apiRef.current.setEditRowsModel(props.editRowsModel); } }, [apiRef, props.editRowsModel]); }