Skip to main content

Row expansion (detail panels)

Give each row an expandable detail panel. Set enableRowExpansion to add an expand/collapse toggle column, and return the panel content from renderDetailPanel.

Loading demo…

Basic usage

<DataTable
columns={columns}
data={rows}
enableRowExpansion
renderDetailPanel={(row) => (
<Box sx={{ p: 2 }}>
<Typography variant="subtitle2">{row.original.name}</Typography>
<Typography variant="body2" color="text.secondary">{row.original.email}</Typography>
</Box>
)}
/>

renderDetailPanel receives the TanStack Row, so row.original is your data object. The panel renders as a full-width row directly beneath its parent.

Which rows can expand

By default every row is expandable. To allow it only for some rows, pass getRowCanExpand — rows where it returns false render no toggle:

<DataTable
enableRowExpansion
getRowCanExpand={(row) => row.original.hasDetails}
renderDetailPanel={(row) => /* … */}
/>

Custom toggle icons

The expander column uses MUI chevrons by default. Swap them via slots:

<DataTable
enableRowExpansion
slots={{ expandIcon: ChevronRight, collapseIcon: ExpandMore }}
renderDetailPanel={/* … */}
/>

Imperative control

The expander column toggles a row for you. For programmatic control (e.g. expand all), reach the underlying TanStack table via apiRef:

apiRef.current?.table.getTable().toggleAllRowsExpanded(true); // expand all
apiRef.current?.table.getTable().toggleAllRowsExpanded(false); // collapse all

Props

PropTypeDescription
enableRowExpansionbooleanAdds the expand/collapse toggle column
renderDetailPanel(row) => ReactNodeContent rendered beneath an expanded row
getRowCanExpand(row) => booleanWhich rows can expand (default: all)

Pin the expander column to keep the toggle visible while scrolling — it's pinned left by default when pinning is enabled (id _expanding).