Row Drag & Drop
Drag any row by its handle to reorder it within the grid. Choose managed mode to let the grid apply the new order automatically, or manual mode to intercept the drop and persist the result yourself.
Enabling row drag
Set rowDrag.enabled: true in GridConfig. A drag handle column
appears automatically on the left. Set rowDrag.position to move it.
readonly config: GridConfig<T> = {
rowDrag: {
enabled: true,
position: 'left', // or 'right'
managed: true,
},
};
Managed vs manual mode
Control what happens after a successful drop with rowDrag.managed:
managed: true— the grid applies the new row order instantly.(rowDragEnd)still fires so you can persist the result to an API.managed: false(default) — the grid emits(rowDragEnd)and waits. Readevent.rows— the full reordered array — and update your data source yourself.
// Manual mode — persist the new order yourself
async onDragEnd(e: RowDragEvent): Promise<void> {
this.data = e.rows; // e.rows = full array in new order
await this.api.saveOrder(e.rows); // persist to server
}
RowDragEvent fields
row— the row that was draggedrows— the complete array in its new orderfromIndex/toIndex— original and final positions (zero-based)
When drag pauses automatically
A manual row order can't survive a view whose order is computed: while a client-side sort
(sortMode: 'client' with active sorts), a client-side filter
(filterApplyMode: 'client' with an active query), or grouping / tree data
is shaping the view, the drag handles disappear and a one-time console message explains why. Clear
the sorts or the filter — or switch off grouping / tree data — and the handles come right back,
nothing to configure. (A grouped or hierarchical view re-buckets rows on every render, so a dropped
row couldn't hold its position anyway.)
Locking specific rows
Set rowDrag.canDrag to a predicate to prevent certain rows from being moved.
Rows where it returns false show no handle.
rowDrag: {
enabled: true,
canDrag: (row) => !row.locked, // lock rows with locked: true
}
Interaction with sorting
Row drag and column sorting can coexist, but applying a sort overrides any manual order. If stable manual ordering matters, disable sorting on those columns or indicate in the UI that re-sorting resets the arrangement.
Auto-scroll
Hold a dragged row near the top or bottom edge of the grid to scroll automatically. Reordering within long lists works without releasing the drag.
Mouse interactions
| Interaction | Effect |
|---|---|
| Drag the ⠿ handle | Lifts the row as a ghost; a drop indicator tracks the target position |
| Hold near top/bottom edge | Auto-scrolls the grid while dragging |
| Drop | Reorders (managed mode) and emits (rowDragEnd) with the full new order |
Applying a column sort overrides any manual row order. If a stable manual arrangement matters, disable sorting on those columns — or make it clear in the UI that sorting resets the order.
Row drag API
| Property | Type | Default | Description |
|---|---|---|---|
| config.rowDrag.enabled | boolean | false | Adds the drag-handle column; position picks the side. |
| config.rowDrag.managed | boolean | false | true lets the grid apply the new order instantly; false emits and waits for you to update the data. |
| config.rowDrag.canDrag | (row) => boolean | — | Rows returning false show no handle and cannot be moved. |
| (rowDragEnd) | RowDragEvent | — | { row, rows, fromIndex, toIndex } — rows is the complete array in its new order; persist it here. |