diff --git a/docs/data/data-grid/master-detail/master-detail.md b/docs/data/data-grid/master-detail/master-detail.md
index cb8614ff1114..d2366d51cdc0 100644
--- a/docs/data/data-grid/master-detail/master-detail.md
+++ b/docs/data/data-grid/master-detail/master-detail.md
@@ -189,6 +189,7 @@ More examples of how to customize the detail panel:
- [One expanded detail panel at a time](/x/react-data-grid/row-recipes/#one-expanded-detail-panel-at-a-time)
- [Expand or collapse all detail panels](/x/react-data-grid/row-recipes/#expand-or-collapse-all-detail-panels)
+- [Toggling detail panels on row click](/x/react-data-grid/row-recipes/#toggling-detail-panels-on-row-click)
## apiRef
diff --git a/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.js b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.js
new file mode 100644
index 000000000000..3c9bdfd9c37e
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.js
@@ -0,0 +1,194 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import Grid from '@mui/material/Grid';
+import Typography from '@mui/material/Typography';
+import Paper from '@mui/material/Paper';
+import Stack from '@mui/material/Stack';
+import { DataGridPro, useGridApiRef } from '@mui/x-data-grid-pro';
+import {
+ randomCreatedDate,
+ randomPrice,
+ randomCurrency,
+ randomCountry,
+ randomCity,
+ randomEmail,
+ randomInt,
+ randomAddress,
+ randomCommodity,
+} from '@mui/x-data-grid-generator';
+
+function DetailPanelContent({ row: rowProp }) {
+ return (
+
+
+
+ {`Order #${rowProp.id}`}
+
+
+
+ Customer information
+
+ {rowProp.customer}
+ {rowProp.email}
+
+
+
+ Shipping address
+
+
+ {rowProp.address}
+
+
+ {`${rowProp.city}, ${rowProp.country.label}`}
+
+
+
+ row.quantity * row.unitPrice,
+ },
+ ]}
+ rows={rowProp.products}
+ sx={{ flex: 1 }}
+ hideFooter
+ />
+
+
+
+ );
+}
+
+const columns = [
+ { field: 'id', headerName: 'Order ID' },
+ { field: 'customer', headerName: 'Customer', width: 200 },
+ { field: 'date', type: 'date', headerName: 'Placed at' },
+ { field: 'currency', headerName: 'Currency' },
+ {
+ field: 'total',
+ type: 'number',
+ headerName: 'Total',
+ valueGetter: (value, row) => {
+ const subtotal = row.products.reduce(
+ (acc, product) => product.unitPrice * product.quantity,
+ 0,
+ );
+ const taxes = subtotal * 0.05;
+ return subtotal + taxes;
+ },
+ },
+];
+
+function generateProducts() {
+ const quantity = randomInt(1, 5);
+ return [...Array(quantity)].map((_, index) => ({
+ id: index,
+ name: randomCommodity(),
+ quantity: randomInt(1, 5),
+ unitPrice: randomPrice(1, 1000),
+ }));
+}
+
+const rows = [
+ {
+ id: 1,
+ customer: 'Matheus',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 2,
+ customer: 'Olivier',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 3,
+ customer: 'Flavien',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 4,
+ customer: 'Danail',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 5,
+ customer: 'Alexandre',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+];
+
+export default function DetailPanelExpandOnRowClick() {
+ const getDetailPanelContent = React.useCallback(
+ ({ row }) => ,
+ [],
+ );
+
+ const getDetailPanelHeight = React.useCallback(() => 400, []);
+
+ const apiRef = useGridApiRef();
+
+ const onRowClick = React.useCallback(
+ (params) => {
+ apiRef.current.toggleDetailPanel(params.id);
+ },
+ [apiRef],
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx
new file mode 100644
index 000000000000..dc5df4e819e9
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx
@@ -0,0 +1,202 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import Grid from '@mui/material/Grid';
+import Typography from '@mui/material/Typography';
+import Paper from '@mui/material/Paper';
+import Stack from '@mui/material/Stack';
+import {
+ DataGridPro,
+ DataGridProProps,
+ GridColDef,
+ GridEventListener,
+ useGridApiRef,
+} from '@mui/x-data-grid-pro';
+import {
+ randomCreatedDate,
+ randomPrice,
+ randomCurrency,
+ randomCountry,
+ randomCity,
+ randomEmail,
+ randomInt,
+ randomAddress,
+ randomCommodity,
+} from '@mui/x-data-grid-generator';
+
+function DetailPanelContent({ row: rowProp }: { row: Customer }) {
+ return (
+
+
+
+ {`Order #${rowProp.id}`}
+
+
+
+ Customer information
+
+ {rowProp.customer}
+ {rowProp.email}
+
+
+
+ Shipping address
+
+
+ {rowProp.address}
+
+ {`${rowProp.city}, ${rowProp.country.label}`}
+
+
+ row.quantity * row.unitPrice,
+ },
+ ]}
+ rows={rowProp.products}
+ sx={{ flex: 1 }}
+ hideFooter
+ />
+
+
+
+ );
+}
+
+const columns: GridColDef<(typeof rows)[number]>[] = [
+ { field: 'id', headerName: 'Order ID' },
+ { field: 'customer', headerName: 'Customer', width: 200 },
+ { field: 'date', type: 'date', headerName: 'Placed at' },
+ { field: 'currency', headerName: 'Currency' },
+ {
+ field: 'total',
+ type: 'number',
+ headerName: 'Total',
+ valueGetter: (value, row) => {
+ const subtotal = row.products.reduce(
+ (acc: number, product: any) => product.unitPrice * product.quantity,
+ 0,
+ );
+ const taxes = subtotal * 0.05;
+ return subtotal + taxes;
+ },
+ },
+];
+
+function generateProducts() {
+ const quantity = randomInt(1, 5);
+ return [...Array(quantity)].map((_, index) => ({
+ id: index,
+ name: randomCommodity(),
+ quantity: randomInt(1, 5),
+ unitPrice: randomPrice(1, 1000),
+ }));
+}
+
+const rows = [
+ {
+ id: 1,
+ customer: 'Matheus',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 2,
+ customer: 'Olivier',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 3,
+ customer: 'Flavien',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 4,
+ customer: 'Danail',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+ {
+ id: 5,
+ customer: 'Alexandre',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ address: randomAddress(),
+ country: randomCountry(),
+ city: randomCity(),
+ currency: randomCurrency(),
+ products: generateProducts(),
+ },
+];
+
+type Customer = (typeof rows)[number];
+
+export default function DetailPanelExpandOnRowClick() {
+ const getDetailPanelContent = React.useCallback<
+ NonNullable
+ >(({ row }) => , []);
+
+ const getDetailPanelHeight = React.useCallback(() => 400, []);
+
+ const apiRef = useGridApiRef();
+
+ const onRowClick = React.useCallback>(
+ (params) => {
+ apiRef.current.toggleDetailPanel(params.id);
+ },
+ [apiRef],
+ );
+
+ return (
+
+
+
+ );
+}
diff --git a/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx.preview b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx.preview
new file mode 100644
index 000000000000..db3ecef167cf
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelExpandOnRowClick.tsx.preview
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/docs/data/data-grid/row-recipes/row-recipes.md b/docs/data/data-grid/row-recipes/row-recipes.md
index 6404572a316c..a21217ac8088 100644
--- a/docs/data/data-grid/row-recipes/row-recipes.md
+++ b/docs/data/data-grid/row-recipes/row-recipes.md
@@ -25,3 +25,9 @@ It checks the status of open panels using the [`useGridSelector` hook](/x/react-
When clicked, it uses [`setExpandedDetailPanels`](/x/api/data-grid/grid-api/#grid-api-prop-setExpandedDetailPanels) from the [Grid API](/x/react-data-grid/api-object/#how-to-use-the-api-object) to expand or collapse all detail panels.
{{"demo": "DetailPanelExpandCollapseAll.js", "bg": "inline", "defaultCodeOpen": false}}
+
+## Toggling detail panels on row click
+
+In the demo below, you can toggle the detail panel by clicking anywhere on the row:
+
+{{"demo": "DetailPanelExpandOnRowClick.js", "bg": "inline", "defaultCodeOpen": false}}