Nested Tables

Give each hierarchy level its own columns — expand a row to open a full child table.

  1. Define child columns

    Unlike row grouping, each level can have its own column set.
    TypeScript
    const divisionColumns = [
    { accessor: "divisionId", label: "Division ID", width: 120 },
    { accessor: "revenue", label: "Revenue", width: 120, type: "number" },
    { accessor: "headcount", label: "Headcount", width: 110, type: "number" },
    { accessor: "location", label: "Location", width: "1fr" },
    ];
  2. Add nestedTable to an expandable column

    Set expandable: true and nestedTable with those child columns.
    TypeScript
    {
    accessor: "companyName",
    label: "Company",
    width: 200,
    expandable: true,
    nestedTable: {
    columns: divisionColumns,
    },
    }
  3. Shape nested data

    Nest child arrays under the rowGrouping keys. Child fields match the nested table columns.
    TypeScript
    {
    id: "co-1",
    companyName: "Acme Corp",
    divisions: [
    {
    divisionId: "D-1",
    revenue: 1200000,
    headcount: 42,
    location: "Austin",
    },
    ],
    }
  4. Wire rowGrouping on the parent table

    Pass rowGrouping and getRowId so expansion stays stable.
    React TSX
    <SimpleTable
    columns={companyColumns}
    rows={rows}
    rowGrouping={["divisions"]}
    getRowId={({ row }) => String(row.id)}
    />

Patterns

Configure the nested table

nestedTable accepts most SimpleTable props (selection, resizing, theme, pagination, and more). rows and state renderers come from the parent and are not set here.

TypeScript
{
accessor: "companyName",
label: "Company",
expandable: true,
nestedTable: {
columns: divisionColumns,
enableRowSelection: true,
columnResizing: true,
autoExpandColumns: true,
},
}

Multi-level nesting

Add nestedTable on a column inside the child columns, and extend rowGrouping accordingly.

TypeScript
// Parent column
{
accessor: "companyName",
expandable: true,
nestedTable: {
columns: [
{
accessor: "divisionName",
expandable: true,
nestedTable: { columns: teamColumns },
},
// ...
],
},
}
// Parent table
rowGrouping: ["divisions", "teams"]

Lazy-load nested rows

Use onRowGroupExpand on the parent (or on a nested level) to fetch children when a row expands — same helpers as row grouping (setLoading, setError, setEmpty).

React TSX
<SimpleTable
columns={columns}
rows={rows}
rowGrouping={["stores", "products"]}
getRowId={({ row }) => String(row.id)}
onRowGroupExpand={async ({ row, isExpanded, groupingKey, setLoading, setError, setEmpty, rowIndexPath }) => {
if (!isExpanded) return;
setLoading(true);
try {
const children = await fetchChildren(row.id, groupingKey);
setLoading(false);
if (children.length === 0) {
setEmpty(true, "No data");
return;
}
// update rows using rowIndexPath / groupingKey
} catch (error) {
setLoading(false);
setError(error.message);
}
}}
/>

Example

Pre-loaded divisions under each company.

Dynamic loading example

Divisions load when a company row expands.

Props

Nested Tables Configuration

PropertyRequiredDescriptionExample
Optional
Renders an independent child table on expand. Requires expandable: true and matching rowGrouping.
nestedTable.columns
Required
Column defs for the nested table — can differ entirely from the parent.
rowGrouping
string[]
Optional
Nested array property names that define the hierarchy (same as row grouping).
getRowId
(props: { row: Row }) => string | number | null | undefined
Optional
Stable row id so expansion survives sort and data updates.
Optional
Lazy-load children on expand. Can be set per nesting level.