diff --git a/docs/data/data-grid/master-detail/master-detail.md b/docs/data/data-grid/master-detail/master-detail.md
index f6c5abbbfc1e5..366506a4786d1 100644
--- a/docs/data/data-grid/master-detail/master-detail.md
+++ b/docs/data/data-grid/master-detail/master-detail.md
@@ -157,6 +157,12 @@ Notice that the toggle column is pinned to make sure that it will always be visi
{{"demo": "FullWidthDetailPanel.js", "bg": "inline", "defaultCodeOpen": false}}
+## Recipes
+
+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)
+
## apiRef
The grid exposes a set of methods that enables all of these features using the imperative `apiRef`. To know more about how to use it, check the [API Object](/x/react-data-grid/api-object/) section.
diff --git a/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.js b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.js
new file mode 100644
index 0000000000000..22070963b4fc8
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.js
@@ -0,0 +1,90 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import { DataGridPro } from '@mui/x-data-grid-pro';
+import {
+ randomCreatedDate,
+ randomCurrency,
+ randomEmail,
+ randomPrice,
+} from '@mui/x-data-grid-generator';
+
+const getDetailPanelContent = ({ row }) => (
+ {`Order #${row.id}`}
+);
+const getDetailPanelHeight = () => 50;
+
+export default function DetailPanelOneExpandedRow() {
+ const [detailPanelExpandedRowIds, setDetailPanelExpandedRowIds] = React.useState(
+ [],
+ );
+
+ const handleDetailPanelExpandedRowIdsChange = React.useCallback((newIds) => {
+ setDetailPanelExpandedRowIds(
+ newIds.length > 1 ? [newIds[newIds.length - 1]] : newIds,
+ );
+ }, []);
+
+ return (
+
+
+
+ );
+}
+
+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' },
+];
+
+const rows = [
+ {
+ id: 1,
+ customer: 'Matheus',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 2,
+ customer: 'Olivier',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 3,
+ customer: 'Flavien',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 4,
+ customer: 'Danail',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 5,
+ customer: 'Alexandre',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+];
diff --git a/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.tsx b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.tsx
new file mode 100644
index 0000000000000..79f15166d5bdc
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.tsx
@@ -0,0 +1,99 @@
+import * as React from 'react';
+import Box from '@mui/material/Box';
+import {
+ DataGridPro,
+ DataGridProProps,
+ GridRowsProp,
+ GridRowId,
+ GridColDef,
+} from '@mui/x-data-grid-pro';
+import {
+ randomCreatedDate,
+ randomCurrency,
+ randomEmail,
+ randomPrice,
+} from '@mui/x-data-grid-generator';
+
+const getDetailPanelContent: DataGridProProps['getDetailPanelContent'] = ({
+ row,
+}) => {`Order #${row.id}`};
+const getDetailPanelHeight: DataGridProProps['getDetailPanelHeight'] = () => 50;
+
+export default function DetailPanelOneExpandedRow() {
+ const [detailPanelExpandedRowIds, setDetailPanelExpandedRowIds] = React.useState<
+ GridRowId[]
+ >([]);
+
+ const handleDetailPanelExpandedRowIdsChange = React.useCallback(
+ (newIds: GridRowId[]) => {
+ setDetailPanelExpandedRowIds(
+ newIds.length > 1 ? [newIds[newIds.length - 1]] : newIds,
+ );
+ },
+ [],
+ );
+
+ return (
+
+
+
+ );
+}
+
+const columns: GridColDef[] = [
+ { 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' },
+];
+
+const rows: GridRowsProp = [
+ {
+ id: 1,
+ customer: 'Matheus',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 2,
+ customer: 'Olivier',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 3,
+ customer: 'Flavien',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 4,
+ customer: 'Danail',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+ {
+ id: 5,
+ customer: 'Alexandre',
+ email: randomEmail(),
+ date: randomCreatedDate(),
+ currency: randomCurrency(),
+ total: randomPrice(1, 1000),
+ },
+];
diff --git a/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.tsx.preview b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.tsx.preview
new file mode 100644
index 0000000000000..8bcb25776e478
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/DetailPanelOneExpandedRow.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
new file mode 100644
index 0000000000000..b032a14754a4a
--- /dev/null
+++ b/docs/data/data-grid/row-recipes/row-recipes.md
@@ -0,0 +1,15 @@
+---
+title: Data Grid - Row customization recipes
+---
+
+# Data Grid - Row customization recipes
+
+
Advanced row customization recipes.
+
+## One expanded detail panel at a time
+
+By default, the [Master detail ](/x/react-data-grid/master-detail/) feature supports multiple expanded detail panels simultaneously.
+
+However, you can [control the expanded detail panels](/x/react-data-grid/master-detail/#controlling-expanded-detail-panels) to have only one detail panel expanded at a time.
+
+{{"demo": "DetailPanelOneExpandedRow.js", "bg": "inline", "defaultCodeOpen": false}}
diff --git a/docs/data/pages.ts b/docs/data/pages.ts
index e5815dae81fdf..f37c5214933bb 100644
--- a/docs/data/pages.ts
+++ b/docs/data/pages.ts
@@ -63,6 +63,7 @@ const pages: MuiPage[] = [
{ pathname: '/x/react-data-grid/master-detail', plan: 'pro' },
{ pathname: '/x/react-data-grid/row-ordering', plan: 'pro' },
{ pathname: '/x/react-data-grid/row-pinning', plan: 'pro' },
+ { pathname: '/x/react-data-grid/row-recipes', title: 'Recipes' },
],
},
{ pathname: '/x/react-data-grid/editing' },
diff --git a/docs/pages/x/react-data-grid/row-recipes.js b/docs/pages/x/react-data-grid/row-recipes.js
new file mode 100644
index 0000000000000..8402f18c13151
--- /dev/null
+++ b/docs/pages/x/react-data-grid/row-recipes.js
@@ -0,0 +1,7 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import * as pageProps from 'docsx/data/data-grid/row-recipes/row-recipes.md?@mui/markdown';
+
+export default function Page() {
+ return ;
+}