Skip to content

MasterDetailPlugin

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.

import { MasterDetailPlugin } from '@toolbox-web/grid/plugins/master-detail';
PropertyDefaultDescription
--tbw-master-detail-bgvar(--tbw-color-row-alt)Detail row background
--tbw-master-detail-bordervar(--tbw-color-border)Detail row border
--tbw-detail-padding1emDetail content padding
--tbw-animation-duration200msExpand/collapse animation
OptionTypeDescription
detailRenderer?(row: Record<string, unknown>, rowIndex: number) => string | HTMLElementRenderer function that returns detail content for a row
detailHeight?number | autoHeight of the detail row - number (pixels) or ‘auto’ (default: ‘auto’)
expandOnRowClick?booleanExpand/collapse detail on row click (default: false)
collapseOnClickOutside?booleanCollapse expanded detail when clicking outside (default: false)
showExpandColumn?booleanShow expand/collapse column (default: true)
animation?ExpandCollapseAnimationAnimation style for expanding/collapsing detail rows. - false: No animation - 'slide': Slide down/up animation (default) - 'fade': Fade in/out animation
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>
`,
}),
],
};
new MasterDetailPlugin({
detailRenderer: (row) => {
const childGrid = document.createElement('tbw-grid');
childGrid.style.height = '200px';
childGrid.gridConfig = { columns: [...] };
childGrid.rows = row.items || [];
return childGrid;
},
})

Extends BaseGridPlugin

Inherited methods like attach(), detach(), afterRender(), etc. are documented in the base class.

PropertyTypeDescription
dependenciesobject[]Optional dependency on ServerSide for async detail data. When loaded, MasterDetail can fetch detail data via datasource:fetch-children.

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 | undefined
NameTypeDescription
rowunknownThe row data
_indexnumberThe row index (unused, but part of the interface)

number | undefined - The row height in pixels (base height for collapsed, base + detail for expanded)


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): number
NameTypeDescription
startnumber
scrollTopnumber
rowHeightnumber

Expand the detail row at the given index.

expand(rowIndex: number): void
NameTypeDescription
rowIndexnumberIndex of the row to expand

Collapse the detail row at the given index.

collapse(rowIndex: number): void
NameTypeDescription
rowIndexnumberIndex of the row to collapse

Toggle the detail row at the given index.

toggle(rowIndex: number): void
NameTypeDescription
rowIndexnumberIndex of the row to toggle

Check if the detail row at the given index is expanded.

isExpanded(rowIndex: number): boolean
NameTypeDescription
rowIndexnumberIndex of the row to check

boolean - Whether the detail row is expanded


Expand all detail rows. Skips synthetic rows (e.g., group headers from GroupingRowsPlugin).

expandAll(): void

Collapse all detail rows.

collapseAll(): void

Get the indices of all expanded rows.

getExpandedRows(): number[]

number[] - Array of row indices that are expanded


Get the detail element for a specific row.

getDetailElement(rowIndex: number): HTMLElement | undefined
NameTypeDescription
rowIndexnumberIndex of the row

HTMLElement | undefined - The detail HTMLElement or undefined


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[] | undefined
NameTypeDescription
rowIndexnumberIndex of the row

unknown[] | undefined - Array of child rows or undefined


Check if detail data is currently being loaded for a row.

isDetailLoading(rowIndex: number): boolean
NameTypeDescription
rowIndexnumberIndex of the row

boolean - Whether the detail is loading


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

AI assistants: For complete API documentation, implementation guides, and code examples for this library, see https://raw.githubusercontent.com/OysteinAmundsen/toolbox/main/llms-full.txt