Documentation

Master-detail and tree data

Two ways to show something inside a row. Master-detail opens a panel you draw yourself; tree data turns a flat list into a hierarchy using a parent reference. Both are Enterprise, and both are silently stripped in Community — turn on debugMode and the console says which.

Master-detail

Two things together: the config, and the renderer.

import { EnterpriseDataGrid } from '@kanunilabs/datagrid-react-enterprise';

<EnterpriseDataGrid
  licenseKey={key}
  dataSource={orders}
  rowKey="id"
  columns={columns}
  masterDetail={{ height: 220 }}
  renderDetail={(order) => <OrderLines orderId={order.id} />}
/>

masterDetail adds the expander column and reserves the row; renderDetail fills it. Give both — the config on its own produces an expander that opens an empty panel.

OptionTypeDefault
masterDetail.heightnumberthe row height
masterDetail.expandedByDefaultbooleanfalse

Driving it from code:

controller.toggleDetail(rowKey);
controller.isDetailExpanded(rowKey);
controller.collapseAllDetails();

See it working →

Tree data

The rows stay flat; the grid builds the hierarchy from a parent reference.

<EnterpriseDataGrid
  licenseKey={key}
  dataSource={employees}      // flat array
  rowKey="id"
  columns={columns}
  tree={{ parentField: 'managerId', defaultExpanded: true }}
/>

A row whose parent is null (or missing) is a root. When the parent key is not a plain field, resolve it yourself:

tree={{ getParentKey: (row) => row.path.split('/').at(-2) ?? null }}

The indent and the twisty land on the first visible column; a leaf keeps the slot so the text stays aligned.

See it working →

What these do not do

  • Tree needs the client row model. Pass a server-side DataSource and the tree is ignored entirely — with no warning. The rows must all be present for the grid to build a hierarchy from them.
  • Tree and grouping are exclusive. With both configured the tree wins and groupBy is ignored; debugMode says so once.
  • One panel height for the whole grid. masterDetail.height is not per-row, and getRowHeight cannot override a detail row.
  • There is no expandAllDetails(). The API has toggleDetail and collapseAllDetails; opening everything is expandedByDefault: true.
  • No dedicated events. Nothing named detailExpanded or treeExpanded exists — expanding republishes contentReady.
  • Saved views do not remember them. A restored view resets open panels deliberately, and tree expansion is not stored either. Only collapsed groups survive.
  • No keyboard expand/collapse. Arrow keys do not open a node; the toggle is the button itself, so Enter and Space work once it has focus. Detail rows are skipped by cell navigation.
  • Export is flat. Detail panels are never written out, and tree rows export as ordinary rows at level 0 — no indentation.
  • Tree selection does not cascade. Ticking a parent does not tick its children; there is no descendant concept in the selection engine.

If any of those is load-bearing for you, say so — several are small, and knowing which one blocks a real project is how they get prioritised.