UNPKG

@mui/x-data-grid

Version:

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

380 lines (316 loc) 13.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.useCellEditing = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var React = _interopRequireWildcard(require("react")); var _utils = require("@mui/material/utils"); var _useGridApiEventHandler = require("../../utils/useGridApiEventHandler"); var _gridEditRowModel = require("../../../models/gridEditRowModel"); var _keyboardUtils = require("../../../utils/keyboardUtils"); var _useGridLogger = require("../../utils/useGridLogger"); var _gridFocusStateSelector = require("../focus/gridFocusStateSelector"); var _useGridApiMethod = require("../../utils/useGridApiMethod"); var _gridEditRowsSelector = require("./gridEditRowsSelector"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function isPromise(promise) { return typeof promise.then === 'function'; } const useCellEditing = (apiRef, props) => { var _props$experimentalFe2; const logger = (0, _useGridLogger.useGridLogger)(apiRef, 'useGridEditRows'); const buildCallback = callback => (...args) => { if (props.editMode === _gridEditRowModel.GridEditModes.Cell) { callback(...args); } }; const setCellMode = React.useCallback((id, field, mode) => { if (apiRef.current.getCellMode(id, field) === mode) { return; } logger.debug(`Switching cell id: ${id} field: ${field} to mode: ${mode}`); apiRef.current.setState(state => { const newEditRowsState = (0, _extends2.default)({}, state.editRows); newEditRowsState[id] = (0, _extends2.default)({}, newEditRowsState[id]); if (mode === _gridEditRowModel.GridCellModes.Edit) { newEditRowsState[id][field] = { value: apiRef.current.getCellValue(id, field) }; } else { delete newEditRowsState[id][field]; if (!Object.keys(newEditRowsState[id]).length) { delete newEditRowsState[id]; } } return (0, _extends2.default)({}, state, { editRows: newEditRowsState }); }); apiRef.current.forceUpdate(); apiRef.current.publishEvent('cellModeChange', apiRef.current.getCellParams(id, field)); }, [apiRef, logger]); const getCellMode = React.useCallback((id, field) => { const editRowsState = (0, _gridEditRowsSelector.gridEditRowsStateSelector)(apiRef.current.state); const isEditing = editRowsState[id] && editRowsState[id][field]; return isEditing ? _gridEditRowModel.GridCellModes.Edit : _gridEditRowModel.GridCellModes.View; }, [apiRef]); // TODO v6: it should always return a promise const commitCellChange = React.useCallback((params, event = {}) => { var _props$experimentalFe; const { id, field } = params; apiRef.current.unstable_runPendingEditCellValueMutation(id, field); const model = apiRef.current.getEditRowsModel(); if (!model[id] || !model[id][field]) { throw new Error(`MUI: Cell at id: ${id} and field: ${field} is not in edit mode.`); } const editCellProps = model[id][field]; const column = apiRef.current.getColumn(field); const row = apiRef.current.getRow(id); if ((_props$experimentalFe = props.experimentalFeatures) != null && _props$experimentalFe.preventCommitWhileValidating) { const cellProps = model[id][field]; if (cellProps.isValidating || cellProps.error) { return false; } } const commitParams = (0, _extends2.default)({}, params, { value: editCellProps.value }); let hasError = !!editCellProps.error; if (!hasError && typeof column.preProcessEditCellProps === 'function') { const result = column.preProcessEditCellProps({ id, row, props: editCellProps }); if (isPromise(result)) { return result.then(newEditCellProps => { apiRef.current.unstable_setEditCellProps({ id, field, props: newEditCellProps }); if (newEditCellProps.error) { return false; } apiRef.current.publishEvent('cellEditCommit', commitParams, event); return true; }); } apiRef.current.unstable_setEditCellProps({ id, field, props: result }); hasError = !!result.error; } if (!hasError) { apiRef.current.publishEvent('cellEditCommit', commitParams, event); return true; } return false; }, [apiRef, (_props$experimentalFe2 = props.experimentalFeatures) == null ? void 0 : _props$experimentalFe2.preventCommitWhileValidating]); const setCellEditingEditCellValue = React.useCallback(params => { const column = apiRef.current.getColumn(params.field); const row = apiRef.current.getRow(params.id); return new Promise(resolve => { let newEditCellProps = { value: params.value }; const model = apiRef.current.getEditRowsModel(); const editCellProps = model[params.id][params.field]; if (typeof column.preProcessEditCellProps !== 'function') { apiRef.current.unstable_setEditCellProps((0, _extends2.default)({}, params, { props: newEditCellProps })); resolve(true); return; } // setEditCellProps runs the value parser and returns the updated props newEditCellProps = apiRef.current.unstable_setEditCellProps((0, _extends2.default)({}, params, { props: (0, _extends2.default)({}, editCellProps, { isValidating: true }) })); Promise.resolve(column.preProcessEditCellProps({ id: params.id, row, props: (0, _extends2.default)({}, newEditCellProps, { value: apiRef.current.unstable_parseValue(params.id, params.field, params.value) }) })).then(newEditCellPropsProcessed => { apiRef.current.unstable_setEditCellProps((0, _extends2.default)({}, params, { props: (0, _extends2.default)({}, newEditCellPropsProcessed, { isValidating: false }) })); resolve(!newEditCellPropsProcessed.error); }); }); }, [apiRef]); const cellEditingApi = { setCellMode, getCellMode, commitCellChange, unstable_setCellEditingEditCellValue: setCellEditingEditCellValue }; (0, _useGridApiMethod.useGridApiMethod)(apiRef, cellEditingApi, 'EditRowApi'); const handleCellKeyDown = React.useCallback(async (params, event) => { // Wait until IME is settled for Asian languages like Japanese and Chinese // TODO: `event.which` is depricated but this is a temporary workaround if (event.which === 229) { return; } const { id, field, cellMode, isEditable } = params; if (!isEditable) { return; } const isEditMode = cellMode === _gridEditRowModel.GridCellModes.Edit; const isModifierKeyPressed = event.ctrlKey || event.metaKey || event.altKey; if (!isEditMode && (0, _keyboardUtils.isCellEnterEditModeKeys)(event) && !isModifierKeyPressed && !(event.key === ' ' && event.shiftKey)) { apiRef.current.publishEvent('cellEditStart', params, event); } if (!isEditMode && (0, _keyboardUtils.isDeleteKeys)(event.key)) { apiRef.current.setEditCellValue({ id, field, value: '' }); apiRef.current.commitCellChange({ id, field }, event); apiRef.current.publishEvent('cellEditStop', params, event); } if (isEditMode && (0, _keyboardUtils.isCellEditCommitKeys)(event.key)) { const commitParams = { id, field }; const isValid = await apiRef.current.commitCellChange(commitParams, event); if (!isValid) { return; } } if (isEditMode && (0, _keyboardUtils.isCellExitEditModeKeys)(event.key)) { apiRef.current.publishEvent('cellEditStop', params, event); } }, [apiRef]); const handleCellDoubleClick = React.useCallback((params, event) => { if (!params.isEditable) { return; } apiRef.current.publishEvent('cellEditStart', params, event); }, [apiRef]); const commitPropsAndExit = async (params, event) => { if (params.cellMode === _gridEditRowModel.GridCellModes.View) { return; } await apiRef.current.commitCellChange(params, event); apiRef.current.publishEvent('cellEditStop', params, event); }; const handleCellFocusOut = (0, _utils.useEventCallback)((params, event) => { commitPropsAndExit(params, event); }); const handleColumnHeaderDragStart = (0, _utils.useEventCallback)(() => { const cell = (0, _gridFocusStateSelector.gridFocusCellSelector)(apiRef); if (!cell) { return; } const params = apiRef.current.getCellParams(cell.id, cell.field); commitPropsAndExit(params, {}); }); const handleCellEditStart = React.useCallback((params, event) => { if (!params.isEditable) { return; } apiRef.current.setCellMode(params.id, params.field, _gridEditRowModel.GridCellModes.Edit); if ((0, _keyboardUtils.isKeyboardEvent)(event) && (0, _keyboardUtils.isPrintableKey)(event)) { apiRef.current.unstable_setEditCellProps({ id: params.id, field: params.field, props: { value: '' } }); } }, [apiRef]); const handleCellEditStop = React.useCallback((params, event) => { apiRef.current.setCellMode(params.id, params.field, _gridEditRowModel.GridCellModes.View); if (!(0, _keyboardUtils.isKeyboardEvent)(event)) { return; } if ((0, _keyboardUtils.isCellEditCommitKeys)(event.key)) { apiRef.current.publishEvent('cellNavigationKeyDown', params, event); return; } if (event.key === 'Escape' || (0, _keyboardUtils.isDeleteKeys)(event.key)) { apiRef.current.setCellFocus(params.id, params.field); } }, [apiRef]); const handleCellEditCommit = React.useCallback(params => { const { id, field } = params; const model = apiRef.current.getEditRowsModel(); const { value } = model[id][field]; logger.debug(`Setting cell id: ${id} field: ${field} to value: ${value == null ? void 0 : value.toString()}`); const row = apiRef.current.getRow(id); if (row) { const column = apiRef.current.getColumn(params.field); let rowUpdate = (0, _extends2.default)({}, row, { [field]: value }); if (column.valueSetter) { rowUpdate = column.valueSetter({ row, value }); } apiRef.current.updateRows([rowUpdate]); } }, [apiRef, logger]); const handleEditCellPropsChange = React.useCallback(params => { const row = apiRef.current.getRow(params.id); const column = apiRef.current.getColumn(params.field); const editCellProps = column.preProcessEditCellProps ? column.preProcessEditCellProps({ id: params.id, row, props: params.props }) : params.props; if (isPromise(editCellProps)) { editCellProps.then(newEditCellProps => { apiRef.current.unstable_setEditCellProps((0, _extends2.default)({}, params, { props: newEditCellProps })); }); } else { apiRef.current.unstable_setEditCellProps((0, _extends2.default)({}, params, { props: editCellProps })); } }, [apiRef]); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellKeyDown', buildCallback(handleCellKeyDown)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellDoubleClick', buildCallback(handleCellDoubleClick)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellFocusOut', buildCallback(handleCellFocusOut)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'columnHeaderDragStart', buildCallback(handleColumnHeaderDragStart)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellEditStart', buildCallback(handleCellEditStart)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellEditStop', buildCallback(handleCellEditStop)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'cellEditCommit', buildCallback(handleCellEditCommit)); (0, _useGridApiEventHandler.useGridApiEventHandler)(apiRef, 'editCellPropsChange', buildCallback(handleEditCellPropsChange)); (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditCommit', props.onCellEditCommit); (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditStart', props.onCellEditStart); (0, _useGridApiEventHandler.useGridApiOptionHandler)(apiRef, 'cellEditStop', props.onCellEditStop); }; exports.useCellEditing = useCellEditing;