From 6c1fbc908c3831720d14e65fb08f1495f99e9499 Mon Sep 17 00:00:00 2001 From: Matheus Wichman Date: Thu, 23 Mar 2023 18:59:04 -0300 Subject: [PATCH 1/4] [docs] Add recipe for single-click editing --- docs/data/data-grid/editing/editing.md | 4 + .../recipes-editing/SingleClickEditing.js | 117 ++++++++++++++++ .../recipes-editing/SingleClickEditing.tsx | 127 ++++++++++++++++++ .../SingleClickEditing.tsx.preview | 7 + .../recipes-editing/recipes-editing.md | 8 ++ 5 files changed, 263 insertions(+) create mode 100644 docs/data/data-grid/recipes-editing/SingleClickEditing.js create mode 100644 docs/data/data-grid/recipes-editing/SingleClickEditing.tsx create mode 100644 docs/data/data-grid/recipes-editing/SingleClickEditing.tsx.preview diff --git a/docs/data/data-grid/editing/editing.md b/docs/data/data-grid/editing/editing.md index de3ee73259673..88a85266f8707 100644 --- a/docs/data/data-grid/editing/editing.md +++ b/docs/data/data-grid/editing/editing.md @@ -39,6 +39,10 @@ Users can start editing a cell (or row if `editMode="row"`) with any of the foll 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 0000000000000..5bd296008f166 --- /dev/null +++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.js @@ -0,0 +1,117 @@ +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) => { + if (!params.isEditable) { + 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 0000000000000..6c1b3d4a0a7a4 --- /dev/null +++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx @@ -0,0 +1,127 @@ +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) => { + if (!params.isEditable) { + 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 0000000000000..e4ad0002f8deb --- /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 42ab8011ea4f7..57c63391dc0a4 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 + +One of the [built-in ways](/x/react-data-grid/editing/#start-editing) to the enter mode is by double-clicking a cell. +Using the [controlled mode](/x/react-data-grid/editing/#controlled-mode) 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. From 06b5d3e42ff47d9a69457498ce4e61d05f00d46b Mon Sep 17 00:00:00 2001 From: Matheus Wichman Date: Fri, 19 May 2023 18:57:57 -0300 Subject: [PATCH 2/4] Ignore clicks from Portals --- .../recipes-editing/SingleClickEditing.js | 7 +- .../recipes-editing/SingleClickEditing.tsx | 66 +++++++++++-------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/docs/data/data-grid/recipes-editing/SingleClickEditing.js b/docs/data/data-grid/recipes-editing/SingleClickEditing.js index 5bd296008f166..9ea1a04920577 100644 --- a/docs/data/data-grid/recipes-editing/SingleClickEditing.js +++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.js @@ -66,11 +66,16 @@ const rows = [ export default function SingleClickEditing() { const [cellModesModel, setCellModesModel] = React.useState({}); - const handleCellClick = React.useCallback((params) => { + 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 diff --git a/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx index 6c1b3d4a0a7a4..97153fcbef661 100644 --- a/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx +++ b/docs/data/data-grid/recipes-editing/SingleClickEditing.tsx @@ -73,38 +73,46 @@ const rows: GridRowsProp = [ export default function SingleClickEditing() { const [cellModesModel, setCellModesModel] = React.useState({}); - const handleCellClick = React.useCallback((params: GridCellParams) => { - if (!params.isEditable) { - return; - } + const handleCellClick = React.useCallback( + (params: GridCellParams, event: React.MouseEvent) => { + if (!params.isEditable) { + 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 } }), + // 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.field]: { mode: GridCellModes.Edit }, - }, - }; - }); - }, []); + [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) => { From 122ab54c899bdbc00353700795caa8aa6319c4fd Mon Sep 17 00:00:00 2001 From: Matheus Wichman Date: Fri, 16 Jun 2023 17:58:48 -0300 Subject: [PATCH 3/4] Minor improvements --- docs/data/data-grid/editing/editing.md | 2 +- docs/data/data-grid/recipes-editing/recipes-editing.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/data-grid/editing/editing.md b/docs/data/data-grid/editing/editing.md index 1aaf73135d32a..9584ceeb2ecc6 100644 --- a/docs/data/data-grid/editing/editing.md +++ b/docs/data/data-grid/editing/editing.md @@ -77,7 +77,7 @@ When a cell is in `view` mode, users can start editing a cell (or row if `editMo ``` :::info -You can also enter edit mode with a single-click by following [this recipe](/x/react-data-grid/recipes-editing/#single-click-editing). +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 diff --git a/docs/data/data-grid/recipes-editing/recipes-editing.md b/docs/data/data-grid/recipes-editing/recipes-editing.md index 42d00c644e2b5..87dc0d9f00f3a 100644 --- a/docs/data/data-grid/recipes-editing/recipes-editing.md +++ b/docs/data/data-grid/recipes-editing/recipes-editing.md @@ -98,10 +98,10 @@ Note that the `onCellEditStart` and `onCellEditStop` props also have to be used {{"demo": "LinkedFieldsCellEditing.js", "bg": "inline", "defaultCodeOpen": false}} -## Single-click editing +## Single click editing -One of the [built-in ways](/x/react-data-grid/editing/#start-editing) to the enter mode is by double-clicking a cell. -Using the [controlled mode](/x/react-data-grid/editing/#controlled-mode) and listening to click events, you can also enter the edit mode with just a single-click. +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-mode) 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}} From c29c34c6de9360ca210abec44b4e2917d79cfe5f Mon Sep 17 00:00:00 2001 From: Matheus Wichman Date: Fri, 16 Jun 2023 19:21:41 -0300 Subject: [PATCH 4/4] Fix links --- docs/data/data-grid/recipes-editing/recipes-editing.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/data-grid/recipes-editing/recipes-editing.md b/docs/data/data-grid/recipes-editing/recipes-editing.md index 87dc0d9f00f3a..30e93b5b796cd 100644 --- a/docs/data/data-grid/recipes-editing/recipes-editing.md +++ b/docs/data/data-grid/recipes-editing/recipes-editing.md @@ -101,7 +101,7 @@ Note that the `onCellEditStart` and `onCellEditStop` props also have to be used ## 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-mode) and listening to click events, you can also enter the edit mode with just a single click. +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}}