# UndoRedoPlugin

> _Since v0.1.1_

Undo/Redo Plugin for tbw-grid

Tracks all cell edits and lets users revert or replay changes with familiar keyboard
shortcuts (Ctrl+Z / Ctrl+Y). Maintains an in-memory history stack with configurable
depth—perfect for data entry workflows where mistakes happen.

&gt; **Required Dependency:** This plugin requires EditingPlugin to be loaded first.
&gt; UndoRedo tracks the edit history that EditingPlugin creates.

## Installation

```ts
import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';
import { UndoRedoPlugin } from '@toolbox-web/grid/plugins/undo-redo';
```

## Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+Z` / `Cmd+Z` | Undo last edit |
| `Ctrl+Y` / `Cmd+Shift+Z` | Redo last undone edit |

## [Configuration Options](/grid/plugins/undo-redo/interfaces/undoredoconfig.md)

| Option | Type | Description |
| ------ | ---- | ----------- |
| `maxHistorySize?` | <code>number</code> | Maximum number of actions to keep in history. Default: 100 |

## Example

### Basic Usage with EditingPlugin

```ts
import { queryGrid } from '@toolbox-web/grid';
import { EditingPlugin } from '@toolbox-web/grid/plugins/editing';
import { UndoRedoPlugin } from '@toolbox-web/grid/plugins/undo-redo';

const grid = queryGrid('tbw-grid');
grid.gridConfig = {
  columns: [
    { field: 'name', header: 'Name', editable: true },
    { field: 'price', header: 'Price', type: 'number', editable: true },
  ],
  plugins: [
    new EditingPlugin({ editOn: 'dblclick' }), // Required - must be first
    new UndoRedoPlugin({ maxHistorySize: 50 }),
  ],
};
```

## See Also

- [`UndoRedoConfig`](/grid/plugins/undo-redo/interfaces/undoredoconfig.md) for configuration options
- EditingPlugin for the required dependency

> **Extends** [BaseGridPlugin](/docs/grid-api-plugin-development-classes-basegridplugin--docs)
>
> Inherited methods like `attach()`, `detach()`, `afterRender()`, etc. are documented in the base class.

## Methods

### recordEdit()

Record a cell edit for undo/redo tracking.
Call this when a cell value changes.

```ts
recordEdit(rowIndex: number, field: string, oldValue: unknown, newValue: unknown): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `rowIndex` | <code>number</code> | The row index where the edit occurred |
| `field` | <code>string</code> | The field (column key) that was edited |
| `oldValue` | <code>unknown</code> | The value before the edit |
| `newValue` | <code>unknown</code> | The value after the edit |

***

### beginTransaction()

Begin grouping subsequent edits into a single compound action.

While a transaction is active, all `recordEdit()` calls (both manual
and auto-recorded from `cell-edit-committed`) are buffered instead of
pushed to the undo stack. Call `endTransaction()` to finalize the group.

**Typical usage** — group a user edit with its cascaded side-effects:

```ts
grid.on('cell-commit', () => {
  const undoRedo = grid.getPluginByName('undoRedo');
  undoRedo.beginTransaction();

  // Record cascaded updates (these won't auto-record)
  const oldB = row.fieldB;
  undoRedo.recordEdit(rowIndex, 'fieldB', oldB, computedB);
  grid.updateRow(rowId, { fieldB: computedB });

  // End after the auto-recorded original edit is captured
  queueMicrotask(() => undoRedo.endTransaction());
});
```

```ts
beginTransaction(): void
```

***

### endTransaction()

Finalize the current transaction, wrapping all buffered edits into a
single compound action on the undo stack.

- If the buffer contains multiple edits, they are wrapped in a `CompoundEditAction`.
- If the buffer contains a single edit, it is pushed as a regular `EditAction`.
- If the buffer is empty, this is a no-op.

Undoing a compound action reverts all edits in reverse order; redoing
replays them in forward order.

```ts
endTransaction(): void
```

***

### undo()

Programmatically undo the last action.

```ts
undo(): UndoRedoAction | null
```

#### Returns

`UndoRedoAction | null` - The undone action, or null if nothing to undo

***

### redo()

Programmatically redo the last undone action.

```ts
redo(): UndoRedoAction | null
```

#### Returns

`UndoRedoAction | null` - The redone action, or null if nothing to redo

***

### canUndo()

Check if there are any actions that can be undone.

```ts
canUndo(): boolean
```

***

### canRedo()

Check if there are any actions that can be redone.

```ts
canRedo(): boolean
```

***

### clearHistory()

Clear all undo/redo history.

```ts
clearHistory(): void
```

***

### getUndoStack()

Get a copy of the current undo stack.

```ts
getUndoStack(): UndoRedoAction[]
```

***

### getRedoStack()

Get a copy of the current redo stack.

```ts
getRedoStack(): UndoRedoAction[]
```

***
