Expandable rows

Pass expandableRows and an expandableRowsComponent to render a detail panel below each row when the user clicks the expander button.

Expandable detail panel

Click the ▶ button to expand a row. Toggle 'Animate expand' or disable 'Restricted' rows with the checkboxes.

Name
Role
Department
Salary
Access
Aria Chen
Engineering Lead
Engineering
$155,000
Open
Marcus Webb
Product Manager
Product
$132,000
Restricted
Priya Kapoor
Senior Designer
Design
$118,000
Open
Jordan Ellis
Data Scientist
Analytics
$143,000
Restricted

The expander component

The component you pass to expandableRowsComponent receives one prop, data, which is the full row object. Type it with the built-in ExpanderComponentProps helper:

import DataTable, { type TableColumn, type ExpanderComponentProps } from 'react-data-table-component';

interface Employee {
  id: number;
  name: string;
  bio: string;
}

// Receives { data: Employee }
const ExpandedRow = ({ data: row }: ExpanderComponentProps<Employee>) => (
  <div style={{ padding: '16px 40px', background: '#f9fafb' }}>
    <strong>{row.name}</strong>
    <p>{row.bio}</p>
  </div>
);

export default function App() {
  return (
    <DataTable
      columns={columns}
      data={data}
      expandableRows
      expandableRowsComponent={ExpandedRow}
    />
  );
}

Passing extra props to the expander

Use expandableRowsComponentProps to inject additional static props into every expander instance. These are merged with the data prop.

const DetailPanel = ({ data: row, onDelete }: { data: Employee; onDelete: (id: number) => void }) => (
  <div style={{ padding: '16px 40px' }}>
    <p>{row.bio}</p>
    <button onClick={() => onDelete(row.id)}>Delete</button>
  </div>
);

<DataTable
  columns={columns}
  data={data}
  expandableRows
  expandableRowsComponent={DetailPanel}
  expandableRowsComponentProps={{ onDelete: handleDelete }}
/>

Controlling which rows are expanded

Use expandableRowExpanded to pre-expand rows on mount. Use expandableRowDisabled to prevent specific rows from being expandable. Their expander icon is hidden and clicks are ignored. Toggle "Disable Restricted rows" in the demo above to see this in action.

// Pre-expand specific rows on mount
<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandableRowExpanded={row => row.featured === true}
/>

// Prevent certain rows from being expanded
<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandableRowDisabled={row => row.locked === true}
/>

Expand on row click

Instead of requiring the user to click the expander icon, you can expand/collapse on a full row click or double-click.

// Single click anywhere on the row expands it
<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandOnRowClicked
/>

// Double-click to expand
<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandOnRowDoubleClicked
/>

// Hide the expander icon entirely (click-to-expand still works)
<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandOnRowClicked
  expandableRowsHideExpander
/>

Reacting to expand / collapse

<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  onRowExpandToggled={(expanded: boolean, row: Employee) => {
    console.log(expanded ? 'opened' : 'closed', row.name);
  }}
/>

Custom expander icons

Override the default collapse/expand icons with any React node via the expandableIcon prop:

<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  expandableIcon={{
    collapsed: <span>&#9654;</span>,
    expanded:  <span>&#9660;</span>,
  }}
/>

Animation

Add animateRows to get a smooth expand-in animation on the detail panel. The animation is automatically disabled when the user's OS has prefers-reduced-motion set.

<DataTable
  expandableRows
  expandableRowsComponent={ExpandedRow}
  animateRows
/>

All expandable props

PropTypeDescription
expandableRowsbooleanEnable expandable rows
expandableRowsComponentComponentType<{ data: T }>Component rendered inside each expanded row
expandableRowsComponentPropsRecord<string, unknown>Extra props injected into every expander instance
expandableRowExpanded(row: T) => booleanPre-expand rows matching this predicate
expandableRowDisabled(row: T) => booleanPrevent rows matching this predicate from being expanded
expandOnRowClickedbooleanExpand/collapse on row click
expandOnRowDoubleClickedbooleanExpand/collapse on row double-click
expandableRowsHideExpanderbooleanHide the expander icon column
expandableIcon{ collapsed: ReactNode; expanded: ReactNode }Custom expand/collapse icons
expandableInheritConditionalStylesbooleanApply the parent row's conditionalRowStyles to the expander row
onRowExpandToggled(expanded: boolean, row: T) => voidFired when a row is expanded or collapsed
animateRowsbooleanAnimate expand/collapse (respects prefers-reduced-motion)