diff --git a/docs/data/data-grid/editing/editing.md b/docs/data/data-grid/editing/editing.md
index cfd2d8ef3dea..9584ceeb2ecc 100644
--- a/docs/data/data-grid/editing/editing.md
+++ b/docs/data/data-grid/editing/editing.md
@@ -76,6 +76,10 @@ When a cell is in `view` mode, users can start editing a cell (or row if `editMo
apiRef.current.startRowEditMode({ id: 1 });
```
+:::info
+You can also enter edit mode with a single click by following [this recipe](/x/react-data-grid/recipes-editing/#single-click-editing).
+:::
+
### Stop editing
When a cell is in `edit` mode, the user can stop editing with any of the following interactions:
diff --git a/docs/data/data-grid/recipes-editing/SingleClickEditing.js b/docs/data/data-grid/recipes-editing/SingleClickEditing.js
new file mode 100644
index 000000000000..9ea1a0492057
--- /dev/null
+++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.js
@@ -0,0 +1,122 @@
+import * as React from 'react';
+import { DataGrid, GridCellModes } from '@mui/x-data-grid';
+import {
+ randomCreatedDate,
+ randomTraderName,
+ randomUpdatedDate,
+} from '@mui/x-data-grid-generator';
+
+const columns = [
+ { field: 'name', headerName: 'Name', width: 180, editable: true },
+ { field: 'age', headerName: 'Age', type: 'number', editable: true },
+ {
+ field: 'dateCreated',
+ headerName: 'Date Created',
+ type: 'date',
+ width: 180,
+ editable: true,
+ },
+ {
+ field: 'lastLogin',
+ headerName: 'Last Login',
+ type: 'dateTime',
+ width: 220,
+ editable: true,
+ },
+];
+
+const rows = [
+ {
+ id: 1,
+ name: randomTraderName(),
+ age: 25,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 2,
+ name: randomTraderName(),
+ age: 36,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 3,
+ name: randomTraderName(),
+ age: 19,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 4,
+ name: randomTraderName(),
+ age: 28,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 5,
+ name: randomTraderName(),
+ age: 23,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+];
+
+export default function SingleClickEditing() {
+ const [cellModesModel, setCellModesModel] = React.useState({});
+
+ const handleCellClick = React.useCallback((params, event) => {
+ if (!params.isEditable) {
+ return;
+ }
+
+ // Ignore portal
+ if (!event.currentTarget.contains(event.target)) {
+ return;
+ }
+
+ setCellModesModel((prevModel) => {
+ return {
+ // Revert the mode of the other cells from other rows
+ ...Object.keys(prevModel).reduce(
+ (acc, id) => ({
+ ...acc,
+ [id]: Object.keys(prevModel[id]).reduce(
+ (acc2, field) => ({
+ ...acc2,
+ [field]: { mode: GridCellModes.View },
+ }),
+ {},
+ ),
+ }),
+ {},
+ ),
+ [params.id]: {
+ // Revert the mode of other cells in the same row
+ ...Object.keys(prevModel[params.id] || {}).reduce(
+ (acc, field) => ({ ...acc, [field]: { mode: GridCellModes.View } }),
+ {},
+ ),
+ [params.field]: { mode: GridCellModes.Edit },
+ },
+ };
+ });
+ }, []);
+
+ const handleCellModesModelChange = React.useCallback((newModel) => {
+ setCellModesModel(newModel);
+ }, []);
+
+ return (
+
+
+
+ );
+}
diff --git a/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx
new file mode 100644
index 000000000000..97153fcbef66
--- /dev/null
+++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx
@@ -0,0 +1,135 @@
+import * as React from 'react';
+import {
+ DataGrid,
+ GridCellModes,
+ GridCellModesModel,
+ GridCellParams,
+ GridRowsProp,
+ GridColDef,
+} from '@mui/x-data-grid';
+import {
+ randomCreatedDate,
+ randomTraderName,
+ randomUpdatedDate,
+} from '@mui/x-data-grid-generator';
+
+const columns: GridColDef[] = [
+ { field: 'name', headerName: 'Name', width: 180, editable: true },
+ { field: 'age', headerName: 'Age', type: 'number', editable: true },
+ {
+ field: 'dateCreated',
+ headerName: 'Date Created',
+ type: 'date',
+ width: 180,
+ editable: true,
+ },
+ {
+ field: 'lastLogin',
+ headerName: 'Last Login',
+ type: 'dateTime',
+ width: 220,
+ editable: true,
+ },
+];
+
+const rows: GridRowsProp = [
+ {
+ id: 1,
+ name: randomTraderName(),
+ age: 25,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 2,
+ name: randomTraderName(),
+ age: 36,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 3,
+ name: randomTraderName(),
+ age: 19,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 4,
+ name: randomTraderName(),
+ age: 28,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+ {
+ id: 5,
+ name: randomTraderName(),
+ age: 23,
+ dateCreated: randomCreatedDate(),
+ lastLogin: randomUpdatedDate(),
+ },
+];
+
+export default function SingleClickEditing() {
+ const [cellModesModel, setCellModesModel] = React.useState({});
+
+ const handleCellClick = React.useCallback(
+ (params: GridCellParams, event: React.MouseEvent) => {
+ if (!params.isEditable) {
+ return;
+ }
+
+ // Ignore portal
+ if (!event.currentTarget.contains(event.target as Element)) {
+ return;
+ }
+
+ setCellModesModel((prevModel) => {
+ return {
+ // Revert the mode of the other cells from other rows
+ ...Object.keys(prevModel).reduce(
+ (acc, id) => ({
+ ...acc,
+ [id]: Object.keys(prevModel[id]).reduce(
+ (acc2, field) => ({
+ ...acc2,
+ [field]: { mode: GridCellModes.View },
+ }),
+ {},
+ ),
+ }),
+ {},
+ ),
+ [params.id]: {
+ // Revert the mode of other cells in the same row
+ ...Object.keys(prevModel[params.id] || {}).reduce(
+ (acc, field) => ({ ...acc, [field]: { mode: GridCellModes.View } }),
+ {},
+ ),
+ [params.field]: { mode: GridCellModes.Edit },
+ },
+ };
+ });
+ },
+ [],
+ );
+
+ const handleCellModesModelChange = React.useCallback(
+ (newModel: GridCellModesModel) => {
+ setCellModesModel(newModel);
+ },
+ [],
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx.preview b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx.preview
new file mode 100644
index 000000000000..e4ad0002f8de
--- /dev/null
+++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx.preview
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/docs/data/data-grid/recipes-editing/recipes-editing.md b/docs/data/data-grid/recipes-editing/recipes-editing.md
index 5af7d6cc1b03..30e93b5b796c 100644
--- a/docs/data/data-grid/recipes-editing/recipes-editing.md
+++ b/docs/data/data-grid/recipes-editing/recipes-editing.md
@@ -98,6 +98,14 @@ Note that the `onCellEditStart` and `onCellEditStop` props also have to be used
{{"demo": "LinkedFieldsCellEditing.js", "bg": "inline", "defaultCodeOpen": false}}
+## Single click editing
+
+By default, one of the ways to [enter the edit mode](/x/react-data-grid/editing/#start-editing) is by double-clicking a cell.
+Using the [controlled mode](/x/react-data-grid/editing/#controlled-model) and listening to click events, you can also enter the edit mode with just a single click.
+The following demo implements this behavior.
+
+{{"demo": "SingleClickEditing.js", "bg": "inline", "defaultCodeOpen": false}}
+
## Usage with `@mui/x-date-pickers`
By default, the data grid uses native browser inputs for editing `date` and `dateTime` columns.