MasterDetailPlugin
Since v0.1.1
Master-Detail Plugin for tbw-grid
Creates expandable detail rows that reveal additional content beneath each master row. Perfect for order/line-item UIs, employee/department views, or any scenario where you need to show related data without navigating away.
Installation
Section titled “Installation”import { MasterDetailPlugin } from '@toolbox-web/grid/plugins/master-detail';CSS Custom Properties
Section titled “CSS Custom Properties”| Property | Default | Description |
|---|---|---|
--tbw-master-detail-bg | var(--tbw-color-row-alt) | Detail row background |
--tbw-master-detail-border | var(--tbw-color-border) | Detail row border |
--tbw-detail-padding | 1em | Detail content padding |
--tbw-animation-duration | 200ms | Expand/collapse animation |
| Option | Type | Description |
|---|---|---|
detailRenderer? | (row: Record<string, unknown>, rowIndex: number) => string | HTMLElement | Renderer function that returns detail content for a row. |
detailHeight? | number | auto | Height of the detail row - number (pixels) or ‘auto’ (default: ‘auto’) |
expandOnRowClick? | boolean | Expand/collapse detail on row click (default: false) |
showExpandColumn? | boolean | Show expand/collapse column (default: true) |
animation? | ExpandCollapseAnimation | Animation style for expanding/collapsing detail rows. - false: No animation - 'slide': Slide down/up animation (default) - 'fade': Fade in/out animation |
Examples
Section titled “Examples”Basic Master-Detail with HTML Template
Section titled “Basic Master-Detail with HTML Template”import '@toolbox-web/grid';import { MasterDetailPlugin } from '@toolbox-web/grid/plugins/master-detail';
grid.gridConfig = { columns: [ { field: 'orderId', header: 'Order ID' }, { field: 'customer', header: 'Customer' }, { field: 'total', header: 'Total', type: 'currency' }, ], plugins: [ new MasterDetailPlugin({ detailRenderer: (row) => ` <div class="order-details"> <h4>Order Items</h4> <ul>${row.items.map(i => `<li>${i.name} - $${i.price}</li>`).join('')}</ul> </div> `, }), ],};Nested Grid in Detail
Section titled “Nested Grid in Detail”new MasterDetailPlugin({ detailRenderer: (row) => { const childGrid = document.createElement('tbw-grid'); childGrid.style.height = '200px'; childGrid.gridConfig = { columns: [...] }; childGrid.rows = row.items || []; return childGrid; },})See Also
Section titled “See Also”MasterDetailConfigfor all configuration optionsDetailExpandDetailfor expand/collapse event details
Extends BaseGridPlugin
Inherited methods like
attach(),detach(),afterRender(), etc. are documented in the base class.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
dependencies | { name: string; required: boolean; reason: string }[] | Optional dependencies. - serverSide: when loaded, MasterDetail can fetch detail data via datasource:fetch-children. - pivot: answers columns:is-replaced, so the expander is left out of the pivot layout (#616). |
Methods
Section titled “Methods”getRowHeight()
Section titled “getRowHeight()”override — Get the height of a specific row, including any expanded detail content.
Always returns a height to ensure the position cache uses plugin-controlled values
rather than stale DOM measurements.
getRowHeight(row: unknown, _index: number): number | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
row | unknown | The row data |
_index | number | The row index (unused, but part of the interface) |
Returns
Section titled “Returns”number | undefined - The row height in pixels (base height for collapsed, base + detail for expanded)
adjustVirtualStart()
Section titled “adjustVirtualStart()”override — Adjust the virtualization start index to keep expanded row visible while its detail is visible.
This ensures the detail scrolls smoothly out of view instead of disappearing abruptly.
adjustVirtualStart(start: number, scrollTop: number, rowHeight: number): numberParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
start | number | |
scrollTop | number | |
rowHeight | number |
expand()
Section titled “expand()”Expand the detail row at the given index.
With ServerSidePlugin active, requests the row’s detail data via getChildRows()
(unless already cached or loading), exactly like clicking the expander.
expand(rowIndex: number): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to expand |
collapse()
Section titled “collapse()”Collapse the detail row at the given index.
collapse(rowIndex: number): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to collapse |
toggle()
Section titled “toggle()”Toggle the detail row at the given index. Expanding requests ServerSide detail data like expand; collapsing aborts an in-flight request.
toggle(rowIndex: number): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to toggle |
isExpanded()
Section titled “isExpanded()”Check if the detail row at the given index is expanded.
isExpanded(rowIndex: number): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row to check |
Returns
Section titled “Returns”boolean - Whether the detail row is expanded
expandAll()
Section titled “expandAll()”Expand all detail rows.
Skips synthetic rows (group headers from GroupingRowsPlugin, ServerSide loading placeholders).
With ServerSidePlugin active, requests detail data for every newly expanded
loaded row (one getChildRows() call per row). Expansion then becomes the
default for every detail row until collapseAll is called, so rows that
appear later — ServerSide blocks replacing loading placeholders, or Tree /
GroupingRows children — render expanded straight away; their detail data is
requested once they scroll into view.
expandAll(): voidcollapseAll()
Section titled “collapseAll()”Collapse all detail rows. Also ends the expandAll mode, so rows appearing later stay collapsed.
collapseAll(): voidgetExpandedRows()
Section titled “getExpandedRows()”Get the indices of all expanded rows.
getExpandedRows(): number[]Returns
Section titled “Returns”number[] - Array of row indices that are expanded, ascending
getDetailElement()
Section titled “getDetailElement()”Get the detail element for a specific row.
getDetailElement(rowIndex: number): HTMLElement | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row |
Returns
Section titled “Returns”HTMLElement | undefined - The detail HTMLElement or undefined
getDetailData()
Section titled “getDetailData()”Get async detail data fetched via ServerSidePlugin for a specific row.
Returns the child rows received from datasource:children after a
datasource:fetch-children query was fired on expand. Returns undefined
when ServerSide is not loaded or data has not arrived yet.
getDetailData(rowIndex: number): unknown[] | undefinedParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row |
Returns
Section titled “Returns”unknown[] | undefined - Array of child rows or undefined
isDetailLoading()
Section titled “isDetailLoading()”Check if detail data is currently being loaded for a row.
isDetailLoading(rowIndex: number): booleanParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
rowIndex | number | Index of the row |
Returns
Section titled “Returns”boolean - Whether the detail is loading
refreshDetailRenderer()
Section titled “refreshDetailRenderer()”Re-parse light DOM to refresh the detail renderer. Call this after framework templates are registered (e.g., Angular ngAfterContentInit).
This allows frameworks to register templates asynchronously and then update the plugin’s detailRenderer.
refreshDetailRenderer(): void