# Master Rows
URL: https://pro.rv-grid.com/guides/data-manage/row-master/
Source: src/content/docs/guides/data-manage/row-master.mdx
Description: A guide to using the Master Row Plugin.
The **Master Row Plugin** enhances the [RevoGrid](https://rv-grid.com/) grid component by enabling the creation and management of master-detail rows.
It is an extremely **complex and advanced feature**, despite its seemingly simple nature. Read more below.

	1.	Dynamic Overlay Synchronization: The Master Row Plugin creates a dynamic overlay that tracks grid scrolling.
  This ensures that master-detail information remains perfectly aligned and visible as you navigate through large datasets.
	2.	Expansive Master Detail Context: Unlike tree view, group view, or merge cell approaches, this plugin uniquely expands the master row context into the pinned area, allowing it to fill the entire grid. This capability provides a richer, more immersive data presentation and is exceptionally challenging to achieve.
	3.	Virtualized Performance: Despite the complexity of rendering an overlay that spans the grid, the layer remains virtualized. This ensures high performance and responsiveness, even when handling extensive and detailed master row content.

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Usage](#usage)
  - [Basic Setup](#basic-setup)
  - [Configuration](#configuration)
  - [Custom Templates](#custom-templates)
  - [Programmatic Expand and Collapse](#programmatic-expand-and-collapse)
- [API Reference](#api-reference)

---

## Features

- **Expandable Rows:** Easily expand rows to reveal additional details.
- **Custom Templates:** Define how master rows are rendered using customizable templates.
---

## Basic Setup

1. **Import Necessary Plugins and Utilities:**

   ```javascript
   import { EXPAND_COLUMN, MasterRowPlugin, CellColumnFocusVerifyPlugin } from '@revolist/revogrid-pro';
   import type { RowMasterConfig } from '@revolist/revogrid';
   import './row-master.style.css';
   ```

2. **Define Columns:**

   ```javascript
   const columns: HTMLRevoGridElement['columns'] = [
     {
       prop: 'expand',
       ...EXPAND_COLUMN,
     },
     // ...
   ];
   ```

3. **Initialize the Grid with Plugins:**

   ```javascript
   const grid = document.querySelector('revo-grid');
     grid.source = makeData(10, 20);
     grid.columns = columns;

     // Define plugin
     grid.plugins = [
       MasterRowPlugin,
     ];

     const masterRow: RowMasterConfig = {
       rowHeight: 100,
       template: (h, data) => {
         return data.model.subRows?.map((subRow: Person) =>
           h('span', { class: { 'master-row': true } }, [
             h('img', { src: subRow.avatar, width: '20', height: '20' }),
             `${subRow.firstName} ${subRow.lastName} `,
           ]),
         );
       },
     };

     grid.masterRow = masterRow;
   }
   ```

### Configuration

The Master Row Plugin can be customized by assigning a `RowMasterConfig` object to `grid.masterRow`. The primary configuration option is the `template` function, which defines how the master row content is rendered.

#### RowMasterConfig

| Property | Type | Description |
| -------- | ---- | ----------- |
| `template` | `(h: Function, data: any) => JSX.Element` | A function that returns the JSX structure for the master row. It receives a rendering function `h` and the data context `data`. |
| `allowDetailEvents` | `readonly string[]` | Event names from the master detail area that are allowed to bubble to the parent grid. All RevoGrid events inside the detail area are stopped by default. |

### Custom Templates

Customize the master row by defining a `template` function that returns the desired JSX structure. This allows for flexible and dynamic rendering based on the row data.

```javascript
const masterRow: RowMasterConfig = {
  template: (h, data) => {
    return data.model.subRows?.map((subRow: Person) =>
      h('div', { class: { 'custom-master-row': true } }, [
        h('img', { src: subRow.avatar, width: '30', height: '30' }),
        `${subRow.firstName} ${subRow.lastName}`,
      ]),
    );
  },
};
```

To let selected events from nested detail content reach the parent grid, add them by name:

```javascript
const masterRow: RowMasterConfig = {
  allowDetailEvents: ['afteredit'],
  template: (h, data) => h('revo-grid', { source: data.model.details }),
};
```

### Programmatic Expand and Collapse

`EXPAND_COLUMN` toggles a single master row by dispatching the `ROW_MASTER` event with the current cell template payload. You can dispatch the same event directly when a toolbar, external control, or custom cell template needs to control master-row state.

For one row, pass the same cell template payload shape used by cell templates. The plugin treats this as a toggle:

```ts
import { ROW_MASTER } from '@revolist/revogrid-pro';

grid.dispatchEvent(new CustomEvent(ROW_MASTER, {
  detail: cellTemplateData,
}));
```

For multiple rows, pass a batch payload with a `rows` array. Each row target declares its desired final state with `expanded: true` or `expanded: false`, so one event can open and close different rows at the same time:

```ts
import { ROW_MASTER } from '@revolist/revogrid-pro';
import type { RowMasterBatchEvent } from '@revolist/revogrid-pro';

const detail: RowMasterBatchEvent = {
  rows: [
    { rowType: 'rgRow', rowIndex: 1, expanded: true },
    { rowType: 'rgRow', rowIndex: 3, expanded: false },
    { rowType: 'rowPinStart', rowIndex: 0, expanded: true },
  ],
};

grid.dispatchEvent(new CustomEvent(ROW_MASTER, { detail }));
```

`rowIndex` is the current virtual row index for the given `rowType`. The plugin converts every target to a stable internal row reference before applying the batch, so one event can safely mix opened and closed rows without later changes shifting earlier targets. If multiple targets resolve to the same row, the last entry wins.

### Automatic Collapse

Expanded master rows are cleared when the grid is about to change row visibility or row structure in a way that can invalidate the detail overlay position.

The plugin calls its internal `clearAllRows()` cleanup when:

- the grid source is replaced
- filtering is about to trim rows through `beforefiltertrimmed`
- row dragging starts

During that cleanup, expanded master rows are collapsed, detail overlay nodes are removed, duplicated detail rows are removed from the row item lists, and custom detail row heights are cleared. This prevents a filtered or replaced row from leaving stale detail height behind after the row itself is no longer visible.

To stop this automatic cleanup for one of these moments, listen for `BEFORE_ROW_MASTER_COLLAPSE` and call `preventDefault()`:

```ts
import { BEFORE_ROW_MASTER_COLLAPSE } from '@revolist/revogrid-pro';

grid.addEventListener(BEFORE_ROW_MASTER_COLLAPSE, (event) => {
  if (event.detail.reason === 'filter') {
    event.preventDefault();
  }
});
```

The event detail includes `reason` (`'source'`, `'filter'`, or `'drag'`) and `rows`, the expanded master rows that are about to be cleared.

Preventing the default cleanup means your application is responsible for handling any stale detail overlays or custom row heights if the related source row is no longer visible.

---

## API Reference

### MasterRowPlugin

A plugin class that manages master-detail rows within the RevoGrid component.

#### Methods

- **constructor(revogrid: HTMLRevoGridElement, providers: PluginProviders)**

  Initializes the plugin with the RevoGrid instance and plugin providers.

- **expandRow(type: DimensionRows, virtRowIndex: number)**

  Expands a specific row to show its master details.

- **collapseRow(type: DimensionRows, rowVIndexes: number[])**

  Collapses one or more rows, hiding their master details.

- **destroy()**

  Cleans up event listeners and other resources when the plugin is destroyed.

#### Events

The plugin listens to various RevoGrid events to manage the state of master rows, including:

- `AFTER_GRID_RENDER_EVENT`
- `BEFORE_ROW_RENDER_EVENT`
- `BEFORE_ROW_MASTER_COLLAPSE` - cancelable event fired before automatic master-row cleanup collapses expanded rows.
- `ROW_MASTER` - toggles one row from a cell template payload, or applies a batch of desired row states with `{ rows: [{ rowType, rowIndex, expanded }] }`.
- `OVERLAY_NODE`
- ...and more.
