# RowReorderPlugin

Row Drag-Drop Plugin for `<tbw-grid>`.

## [Configuration Options](/grid/plugins/row-drag-drop/interfaces/rowdragdropconfig.md)

| Option | Type | Description |
| ------ | ---- | ----------- |
| `enableKeyboard?` | <code>boolean</code> | Enable keyboard shortcuts (`Ctrl + ↑` / `Ctrl + ↓`) for moving rows. Keyboard moves are intra-grid only. |
| `showDragHandle?` | <code>boolean</code> | Show a drag handle column. |
| `dragFrom?` | <code>row &#124; handle &#124; both</code> | Where on a row a drag can be initiated. |
| `dragHandlePosition?` | <code>left &#124; right</code> | Position of the drag handle column. |
| `dragHandleWidth?` | <code>number</code> | Width of the drag handle column in pixels. |
| `debounceMs?` | <code>number</code> | Debounce time in milliseconds for rapid keyboard moves. Events are batched and emitted after this delay. |
| `animation?` | <code>false &#124; flip</code> | Animation type for row movement. - `false`: instant reorder - `'flip'`: FLIP animation (slides rows smoothly) |
| `canDrag?` | <code>(row: T, index: number) =&gt; boolean</code> | Validation callback invoked once at `dragstart` (and on intra-grid keyboard moves) to decide whether a row can be picked up. Replaces `RowReorderConfig.canMove` for the dragstart side. |
| `canMove?` | <code>(row: T, fromIndex: number, toIndex: number, direction: up &#124; down) =&gt; boolean</code> |  |
| `dropZone?` | <code>string</code> | Shared zone identifier. Two grids that opt into the same zone may exchange rows. Omit to behave exactly like the legacy `RowReorderPlugin` — intra-grid only, no cross-grid affordances. |
| `operation?` | <code>copy &#124; move</code> | Cross-grid drop semantics. - `'move'` (default): the row is removed from the source grid's `_rows`   and inserted into the target. - `'copy'`: the source `_rows` is unchanged; the target inserts a copy. |
| `canDrop?` | <code>(payload: <a href="/grid/plugins/row-drag-drop/interfaces/rowdragpayload/">RowDragPayload</a>&lt;T&gt;, targetIndex: number) =&gt; boolean</code> | Validation callback invoked during `dragover` (same-window) and at drop time to decide whether a drop should be accepted at `targetIndex`. |
| `serializeRow?` | <code>(row: T) =&gt; unknown</code> | Optional row transformer applied when a row leaves this grid in a cross-window / cross-iframe drag (i.e. when the WeakRef live-reference path cannot be used). Use to strip internal IDs or rename fields before the row crosses a security boundary. |
| `deserializeRow?` | <code>(raw: unknown) =&gt; T</code> | Optional row transformer applied when a row lands in this grid via a cross-window / cross-iframe drag. Use to assign new IDs or remap fields. |
| `autoScroll?` | <code>boolean &#124; object</code> | Auto-scroll the target grid when the cursor approaches its viewport top or bottom edge during drag. |

## Examples

### Intra-grid (parity with deprecated RowReorderPlugin)

```ts
import { RowDragDropPlugin } from '@toolbox-web/grid/plugins/row-drag-drop';

grid.gridConfig = {
  plugins: [new RowDragDropPlugin()],
};
```

### Cross-grid transfer list

```ts
gridA.gridConfig = { plugins: [new RowDragDropPlugin({ dropZone: 'tasks' })] };
gridB.gridConfig = { plugins: [new RowDragDropPlugin({ dropZone: 'tasks' })] };

gridA.addEventListener('row-transfer', (e) => persist(e.detail));
gridB.addEventListener('row-transfer', (e) => persist(e.detail));
```

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

## Methods

### moveRow()

Move a row to a new position programmatically (intra-grid).

```ts
moveRow(fromIndex: number, toIndex: number): void
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `fromIndex` | <code>number</code> |  |
| `toIndex` | <code>number</code> |  |

***

### canMoveRow()

Check if a row can be moved within this grid.
Consults the user-provided `canMove` callback (or `canDrag` veto for the
source row), the plugin query system (`canMoveRow`), and `canDrop` for
the target.

```ts
canMoveRow(fromIndex: number, toIndex: number): boolean
```

#### Parameters

| Name | Type | Description |
| ---- | ---- | ----------- |
| `fromIndex` | <code>number</code> |  |
| `toIndex` | <code>number</code> |  |

***
