Row Expanding / Master-Detail

Expand rows to show detail content below them. Useful for master-detail patterns.

How to Enable

const table = useTable({
  data,
  columns,
  enableExpanding: true,
  renderDetailPanel: (row) => (
    <div>
      <h3>Details for {row.original.name}</h3>
      <p>Email: {row.original.email}</p>
    </div>
  ),
})

Programmatic Control

// Expand a row
table.getRow('0').toggleExpanded(true)

// Expand all rows
table.toggleAllRowsExpanded(true)

// Collapse all
table.toggleAllRowsExpanded(false)

// Check expansion state
table.getRow('0').getIsExpanded() // boolean
table.getIsAllRowsExpanded() // boolean

With row virtualization

Detail panels still render when enableVirtualization is on, but the virtualizer sizes rows only from rowHeight / Pretext heights — it does not measure the detail panel's DOM height. So a variable-height inline panel is not reflected in the scrollbar or in the position of rows below it: within one mounted window the panel flows correctly, but scrolling past an expanded row drifts the window out of alignment.

For detail content on large, virtualized datasets:

  • Out-of-table detail (preferred) — open the detail in a drawer, modal, or side panel on row click. Every row keeps a predictable height.
  • Disable virtualization for expansion-heavy views where the dataset is small enough to render fully.
  • Fixed-height panels only — if you must expand inline while virtualized, keep the panel one known height and encode it in a rowHeight(index) function that returns base + panelHeight for expanded rows. Variable-height inline panels are not supported under virtualization.