# DataGridEventMap

> _Since v0.1.1_

Maps event names to their detail payload types.

Used by grid.on() and `addEventListener()` for
fully typed event handling. Plugins extend this map via module augmentation.

#### Example

```typescript
// Recommended: grid.on() auto-unwraps the detail
const off = grid.on('cell-click', ({ field, value, row }) => {
  console.log(`Clicked ${field} = ${value}`);
});
off(); // unsubscribe

// addEventListener works too (useful for { once, signal, capture })
grid.addEventListener('cell-click', (e) => {
  console.log(e.detail.field);
}, { once: true });
```

## Core Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `cell-click` | <code><a href="/grid/api/core/interfaces/cellclickdetail/">CellClickDetail</a>&lt;TRow&gt;</code> | Fired when a cell is clicked. Provides full context: row data, column config, cell element, and the original mouse event. |
| `row-click` | <code><a href="/grid/api/core/interfaces/rowclickdetail/">RowClickDetail</a>&lt;TRow&gt;</code> | Fired when a row is clicked (anywhere on the row). Use for row-level actions like opening a detail panel or navigating. |
| `cell-activate` | <code><a href="/grid/api/core/interfaces/cellactivatedetail/">CellActivateDetail</a>&lt;TRow&gt;</code> | Fired when a cell is activated by Enter key or pointer click. Unified event for both keyboard and pointer activation. |
| `cell-change` | <code><a href="/grid/api/core/interfaces/cellchangedetail/">CellChangeDetail</a>&lt;TRow&gt;</code> | Fired after any data mutation — user edits, cascade updates, or API calls. This is an informational event for logging, auditing, or cascading updates to related fields. Check `source` to distinguish edit origins. |
| `data-change` | <code><a href="/grid/api/core/interfaces/datachangedetail/">DataChangeDetail</a></code> | Fired whenever the grid's row data changes — new data assignment, row insertion/removal, or in-place mutations via `updateRow()`. Use to keep external UI (row counts, summaries, charts) in sync. |
| `tbw-scroll` | <code><a href="/grid/api/core/interfaces/tbwscrolldetail/">TbwScrollDetail</a></code> | Fired when the grid's viewport is scrolled vertically (rAF-batched). Use to trigger pagination, defer heavy cell content, dismiss overlays, or sync external UI to the grid's scroll position. |
| `sort-change` | <code><a href="/grid/api/core/interfaces/sortchangedetail/">SortChangeDetail</a></code> | Fired when the sort state changes — column header click, programmatic sort, or sort cleared. `direction: 0` indicates the sort was removed. |
| `column-resize` | <code><a href="/grid/api/core/interfaces/columnresizedetail/">ColumnResizeDetail</a></code> | Fired when a column is resized by the user dragging the resize handle. Use to persist column widths to user preferences or localStorage. |
| `column-resize-reset` | <code><a href="/grid/api/core/interfaces/columnresizeresetdetail/">ColumnResizeResetDetail</a></code> | Fired when a user-resized column is reset to its original configured width. Triggered by the column header context menu "Reset width" action. |
| `column-state-change` | <code><a href="/grid/api/core/interfaces/gridcolumnstate/">GridColumnState</a></code> | Fired when column state changes — reordering, resizing, visibility toggle, or sort changes. Use with `getColumnState()` / `columnState` setter for full state persistence. |
| `render` | <code><a href="/grid/api/core/interfaces/renderdetail/">RenderDetail</a></code> | Fired once at the end of every render cycle, after all plugin `afterRender` hooks have run and `ready()` has resolved. <span class="since-badge" title="Introduced in v2.15.0">v2.15.0+</span> |

### Property Details

#### cell-click

```typescript
grid.on('cell-click', ({ row, field, value, cellEl }) => {
  console.log(`Clicked ${field} = ${value}`);

  // Open a detail dialog for a specific column
  if (field === 'avatar') {
    showImagePreview(row.avatarUrl, cellEl);
  }
});
```

**See also:** [`CellClickDetail`](/grid/api/core/interfaces/cellclickdetail.md)

---

#### row-click

```typescript
grid.on('row-click', ({ row, rowIndex }) => {
  console.log(`Row ${rowIndex}: ${row.name}`);

  // Navigate to detail page
  router.navigate(`/employees/${row.id}`);
});
```

**See also:** [`RowClickDetail`](/grid/api/core/interfaces/rowclickdetail.md)

---

#### cell-activate

Fired when a cell is activated by Enter key or pointer click.
Unified event for both keyboard and pointer activation.

Call `event.preventDefault()` to suppress default behavior (e.g., inline editing).

```typescript
grid.on('cell-activate', ({ row, field, trigger, cellEl }, event) => {
  // Custom editing for a specific column
  if (field === 'notes') {
    event.preventDefault();
    openRichTextEditor(row, cellEl);
  }

  console.log(`Activated via ${trigger}`); // 'keyboard' | 'pointer'
});
```

**See also:** [`CellActivateDetail`](/grid/api/core/interfaces/cellactivatedetail.md) · [`CellActivateTrigger`](/grid/api/core/types/cellactivatetrigger.md)

---

#### cell-change

```typescript
grid.on('cell-change', ({ row, rowId, field, oldValue, newValue, source }) => {
  console.log(`${field}: ${oldValue} → ${newValue} (${source})`);

  // Cascade: recalculate total when quantity changes
  if (source === 'user' && field === 'quantity') {
    grid.updateRow(rowId, { total: newValue * row.price });
  }
});
```

**See also:** [`CellChangeDetail`](/grid/api/core/interfaces/cellchangedetail.md) · [`UpdateSource`](/grid/api/core/types/updatesource.md)

---

#### data-change

```typescript
grid.on('data-change', ({ rowCount, sourceRowCount }) => {
  statusBar.textContent = `${rowCount} of ${sourceRowCount} rows`;
});
```

**See also:** [`DataChangeDetail`](/grid/api/core/interfaces/datachangedetail.md)

---

#### tbw-scroll

Fired when the grid's viewport is scrolled vertically (rAF-batched).
Use to trigger pagination, defer heavy cell content, dismiss overlays,
or sync external UI to the grid's scroll position.

For server-side pagination of large datasets, prefer the
`ServerSidePlugin` — it handles block fetching out of the box.

```typescript
// Infinite scroll
grid.on('tbw-scroll', ({ scrollTop, scrollHeight, clientHeight }) => {
  if (scrollTop + clientHeight >= scrollHeight - 200) loadMore();
});

// Defer heavy cell content (Angular @defer style)
grid.on('tbw-scroll', ({ scrollTop }) => {
  updateVisibleHeavyCells(scrollTop);
});

// Dismiss tooltip/popover on scroll
grid.on('tbw-scroll', () => closeOpenOverlays());
```

**See also:** [`TbwScrollDetail`](/grid/api/core/interfaces/tbwscrolldetail.md)

---

#### sort-change

```typescript
grid.on('sort-change', ({ field, direction }) => {
  if (direction === 0) {
    console.log('Sort cleared');
  } else {
    console.log(`Sorted by ${field} ${direction === 1 ? 'ASC' : 'DESC'}`);
  }

  // Server-side sorting
  fetchData({ sortBy: field, sortDir: direction });
});
```

**See also:** [`SortChangeDetail`](/grid/api/core/interfaces/sortchangedetail.md) · [`SortHandler`](/grid/api/core/types/sorthandler.md)

---

#### column-resize

```typescript
grid.on('column-resize', ({ field, width }) => {
  console.log(`Column "${field}" resized to ${width}px`);

  // Persist to localStorage
  const widths = JSON.parse(localStorage.getItem('col-widths') ?? '{}');
  widths[field] = width;
  localStorage.setItem('col-widths', JSON.stringify(widths));
});
```

**See also:** [`ColumnResizeDetail`](/grid/api/core/interfaces/columnresizedetail.md)

---

#### column-resize-reset

```typescript
grid.on('column-resize-reset', ({ field, width }) => {
  const widths = JSON.parse(localStorage.getItem('col-widths') ?? '{}');
  delete widths[field];
  localStorage.setItem('col-widths', JSON.stringify(widths));
});
```

**See also:** [`ColumnResizeResetDetail`](/grid/api/core/interfaces/columnresizeresetdetail.md)

---

#### column-state-change

```typescript
grid.on('column-state-change', (state) => {
  localStorage.setItem('grid-state', JSON.stringify(state));
  console.log(`${state.columns.length} columns in state`);
});

// Restore on load
const saved = localStorage.getItem('grid-state');
if (saved) grid.applyColumnState(JSON.parse(saved));
```

**See also:** [`GridColumnState`](/grid/api/core/interfaces/gridcolumnstate.md) · [`ColumnState`](/grid/api/core/interfaces/columnstate.md)

---

#### render

Fired once at the end of every render cycle, after all plugin
`afterRender` hooks have run and `ready()` has resolved.

This is the canonical post-render hook for consumers. Use it instead of
`setTimeout` / double-`requestAnimationFrame` to act on the rendered DOM
after a programmatic mutation.

Note: `ready()` only resolves once (after the first render). The `render`
event fires on every flush — including scroll-driven virtual-window
updates — so prefer `{ once: true }` (or check `detail.phase`) when you
want to act on a specific mutation.

```typescript
// Focus the first cell's input after addRow in full-grid edit mode
grid.addRow({ id: crypto.randomUUID(), name: '', email: '' });
grid.addEventListener(
  'render',
  () => {
    const input = grid.querySelector<HTMLInputElement>(
      '[data-row="0"][data-col="0"] input',
    );
    input?.focus();
  },
  { once: true },
);
```

**See also:** [`RenderDetail`](/grid/api/core/interfaces/renderdetail.md)

---

## Framework Adapter Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `mount-external-view` | <code><a href="/grid/api/framework-adapters/interfaces/externalmountviewdetail/">ExternalMountViewDetail</a>&lt;TRow&gt;</code> | Emitted when a cell with an external view renderer (React, Angular, Vue component) needs to be mounted. Framework adapters listen for this event internally. |
| `mount-external-editor` | <code><a href="/grid/api/framework-adapters/interfaces/externalmounteditordetail/">ExternalMountEditorDetail</a>&lt;TRow&gt;</code> | Emitted when a cell with an external editor component (React, Angular, Vue) needs to be mounted with commit/cancel bindings. Framework adapters listen for this event internally. |

### Property Details

#### mount-external-view

```typescript
// Custom framework adapter
grid.on('mount-external-view', ({ placeholder, spec, context }) => {
  myFramework.render(spec.component, placeholder, {
    row: context.row,
    value: context.value,
  });
});
```

**See also:** [`ExternalMountViewDetail`](/grid/api/framework-adapters/interfaces/externalmountviewdetail.md) · [`FrameworkAdapter`](/grid/api/framework-adapters/interfaces/frameworkadapter.md)

---

#### mount-external-editor

```typescript
// Custom framework adapter
grid.on('mount-external-editor', ({ placeholder, spec, context }) => {
  myFramework.render(spec.component, placeholder, {
    value: context.value,
    onSave: context.commit,
    onCancel: context.cancel,
  });
});
```

**See also:** [`ExternalMountEditorDetail`](/grid/api/framework-adapters/interfaces/externalmounteditordetail.md) · [`FrameworkAdapter`](/grid/api/framework-adapters/interfaces/frameworkadapter.md)

---

## Clipboard Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `copy` | <code><a href="/grid/plugins/clipboard/interfaces/copydetail/">CopyDetail</a></code> | Fired after a successful copy operation. Provides the copied text, row count, and column count. |
| `paste` | <code><a href="/grid/plugins/clipboard/interfaces/pastedetail/">PasteDetail</a></code> | Fired after a paste operation. Provides parsed rows, target cell, and column fields. |

## Context Menu Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `context-menu-open` | <code><a href="/grid/plugins/context-menu/interfaces/contextmenuopendetail/">ContextMenuOpenDetail</a></code> | Fired when the context menu opens. Provides the trigger context and resolved menu items. |

## Editing Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `cell-cancel` | <code><a href="/grid/plugins/editing/interfaces/cellcanceldetail/">CellCancelDetail</a></code> | Fired when a cell edit is canceled (Escape key). The cell reverts to its previous value. |
| `cell-commit` | <code><a href="/grid/plugins/editing/interfaces/cellcommitdetail/">CellCommitDetail</a>&lt;TRow&gt;</code> | Fired when a cell value is committed (cancelable). |
| `row-commit` | <code><a href="/grid/plugins/editing/interfaces/rowcommitdetail/">RowCommitDetail</a>&lt;TRow&gt;</code> | Fired when a row editing session ends. |
| `changed-rows-reset` | <code><a href="/grid/plugins/editing/interfaces/changedrowsresetdetail/">ChangedRowsResetDetail</a>&lt;TRow&gt;</code> | Fired when changed rows tracking is reset. |
| `edit-open` | <code><a href="/grid/plugins/editing/interfaces/editopendetail/">EditOpenDetail</a>&lt;TRow&gt;</code> | Fired when a row enters edit mode (row mode only, not grid mode). |
| `before-edit-close` | <code><a href="/grid/plugins/editing/interfaces/beforeeditclosedetail/">BeforeEditCloseDetail</a>&lt;TRow&gt;</code> | Fired synchronously before editing state is cleared. Commit callbacks are still active. |
| `edit-close` | <code><a href="/grid/plugins/editing/interfaces/editclosedetail/">EditCloseDetail</a>&lt;TRow&gt;</code> | Fired when a row leaves edit mode, whether committed or reverted (row mode only). |
| `dirty-change` | <code><a href="/grid/plugins/editing/interfaces/dirtychangedetail/">DirtyChangeDetail</a>&lt;TRow&gt;</code> | Fired when a row's dirty state changes (requires `dirtyTracking: true`). |
| `baselines-captured` | <code><a href="/grid/plugins/editing/interfaces/baselinescaptureddetail/">BaselinesCapturedDetail</a></code> | Fired after the render pipeline completes when new baselines were captured (requires `dirtyTracking: true`). |

## Export Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `export-complete` | <code><a href="/grid/plugins/export/interfaces/exportcompletedetail/">ExportCompleteDetail</a></code> | Fired when an export operation completes. Provides the format, filename, and row/column counts. |

## Filtering Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `filter-change` | <code><a href="/grid/plugins/filtering/interfaces/filterchangedetail/">FilterChangeDetail</a></code> | Fired when filter criteria change. Respects `silent: true` batching — only the final non-silent call emits. |

## Grouping Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `group-toggle` | <code><a href="/grid/plugins/grouping-rows/interfaces/grouptoggledetail/">GroupToggleDetail</a></code> | Fired when a row group is expanded or collapsed. |
| `group-expand` | <code><a href="/grid/plugins/grouping-rows/interfaces/groupexpanddetail/">GroupExpandDetail</a></code> | Fired when a pre-defined group is expanded. |
| `group-collapse` | <code><a href="/grid/plugins/grouping-rows/interfaces/groupcollapsedetail/">GroupCollapseDetail</a></code> | Fired when a pre-defined group is collapsed. |

## Master-Detail Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `detail-expand` | <code><a href="/grid/plugins/master-detail/interfaces/detailexpanddetail/">DetailExpandDetail</a></code> | Fired when a detail panel is expanded or collapsed. |

## Print Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `print-start` | <code><a href="/grid/plugins/print/interfaces/printstartdetail/">PrintStartDetail</a></code> | Fired when printing begins. Provides row count and whether a limit was applied. |
| `print-complete` | <code><a href="/grid/plugins/print/interfaces/printcompletedetail/">PrintCompleteDetail</a></code> | Fired when printing completes. Provides success status, row count, and duration. |

## Column Reorder Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `column-move` | <code><a href="/grid/plugins/reorder-columns/interfaces/columnmovedetail/">ColumnMoveDetail</a></code> | Fired when a column is reordered via drag-and-drop (cancelable). Call `preventDefault()` to reject the move. |

## Responsive Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `responsive-change` | <code><a href="/grid/plugins/responsive/interfaces/responsivechangedetail/">ResponsiveChangeDetail</a></code> | Fired when the grid crosses a responsive breakpoint. |

## Row Drag-Drop Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `row-move` | <code><a href="/grid/plugins/row-drag-drop/interfaces/rowmovedetail/">RowMoveDetail</a>&lt;TRow&gt;</code> | Fired when a row is reordered within a single grid (drag or keyboard). Cancelable — call `preventDefault()` to revert the move. Cross-grid drops emit `row-transfer` / `row-drop` instead. |
| `row-drag-start` | <code><a href="/grid/plugins/row-drag-drop/interfaces/rowdragstartdetail/">RowDragStartDetail</a>&lt;TRow&gt;</code> | Fired on the **source** grid when a row drag begins. Cancelable — call `preventDefault()` to abort the drag. |
| `row-drag-end` | <code><a href="/grid/plugins/row-drag-drop/interfaces/rowdragenddetail/">RowDragEndDetail</a>&lt;TRow&gt;</code> | Fired on the **source** grid when a row drag ends, regardless of outcome. `detail.accepted` is `true` only for cross-grid drops that landed. |
| `row-drop` | <code><a href="/grid/plugins/row-drag-drop/interfaces/rowdropdetail/">RowDropDetail</a>&lt;TRow&gt;</code> | Fired on the **target** grid when a cross-grid drop is about to be applied. Cancelable — call `preventDefault()` to reject the drop. Not fired for intra-grid moves (those still emit `row-move`). |
| `row-transfer` | <code><a href="/grid/plugins/row-drag-drop/interfaces/rowtransferdetail/">RowTransferDetail</a>&lt;TRow&gt;</code> | Fired on **both** the source and target grid after a successful cross-grid drop. Use this to persist changes in your data store. |

## Selection Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `selection-change` | <code><a href="/grid/plugins/selection/interfaces/selectionchangedetail/">SelectionChangeDetail</a></code> | Fired when the selection changes — row click, range drag, Ctrl+click, or programmatic update. |

## Tree Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `tree-expand` | <code><a href="/grid/plugins/tree/interfaces/treeexpanddetail/">TreeExpandDetail</a></code> | Fired when a tree node is expanded or collapsed. Provides the node key, row data, and depth level. |
| `tree-load-start` | <code>void</code> | Fired when lazy tree data starts loading. |
| `tree-load-end` | <code>object</code> | Fired when lazy tree data finishes loading. |
| `tree-load-error` | <code>object</code> | Fired when lazy tree data loading fails. |

## Undo/Redo Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `undo` | <code><a href="/grid/plugins/undo-redo/interfaces/undoredodetail/">UndoRedoDetail</a></code> | Fired after an undo operation (Ctrl+Z). Provides the undone action. |
| `redo` | <code><a href="/grid/plugins/undo-redo/interfaces/undoredodetail/">UndoRedoDetail</a></code> | Fired after a redo operation (Ctrl+Y). Provides the redone action. |

## Visibility Events

| Property | Type | Description |
| -------- | ---- | ----------- |
| `column-reorder-request` | <code><a href="/grid/plugins/visibility/interfaces/columnreorderrequestdetail/">ColumnReorderRequestDetail</a></code> | Fired when the user drag-reorders columns in the visibility sidebar panel. Consumed by `ReorderPlugin` to perform the actual column move. |
| `column-visibility` | <code><a href="/grid/plugins/visibility/interfaces/columnvisibilitydetail/">ColumnVisibilityDetail</a></code> | Fired when a column is shown or hidden — either via the visibility sidebar, `grid.toggleColumnVisibility(field)`, `grid.setColumnVisible(field, visible)`, or `grid.showAllColumns()`. The `field` and `visible` properties are present for single-column toggles and undefined for bulk operations (`showAllColumns`); `visibleColumns` always lists the current set. |

## See Also

- [`DataGridElement.on`](/grid/api/core/classes/datagridelement.md#on) for the recommended subscription API
- [`DataGridCustomEvent`](/grid/api/core/types/datagridcustomevent.md) for typed CustomEvent wrapper
