Column Reorder
The Column Reorder plugin enables column rearrangement by dragging header cells. It supports locking columns in place via lockPosition, preventing cross-zone dragging for pinned columns, and swapping columns programmatically. A movement threshold prevents accidental reorders during header clicks.
Installation
npm install @gridstorm/plugin-column-reorder
Setup
import { createGrid } from '@gridstorm/core';
import { ColumnReorderPlugin } from '@gridstorm/plugin-column-reorder';
const grid = createGrid({
columns: [
{ colId: 'id', field: 'id', headerName: 'ID', lockPosition: true },
{ colId: 'name', field: 'name', headerName: 'Name' },
{ colId: 'age', field: 'age', headerName: 'Age' },
{ colId: 'email', field: 'email', headerName: 'Email' },
],
rowData: [],
plugins: [
ColumnReorderPlugin({
enableDragDrop: true,
lockPinnedColumns: true,
dragIndicatorClass: 'gs-column-drag-indicator',
}),
],
});
:::example{title="Column Reorder Demo" href="/cookbook/#column-reorder"}
Drag column headers to rearrange their order. Columns with lockPosition stay fixed, and pinned zones are protected from cross-zone dragging.
:::
Plugin Options
| Name | Type | Default | Description |
|---|---|---|---|
enableDragDrop |
boolean |
true |
Enable drag-and-drop reordering on header cells. |
lockPinnedColumns |
boolean |
true |
Prevent dragging columns across pin zones (left-pinned, center, right-pinned). |
dragIndicatorClass |
string |
'gs-column-drag-indicator' |
CSS class for the drag ghost element. |
Usage Examples
Move a Column to a Specific Index
grid.commandBus.dispatch('column:move', {
colId: 'email',
toIndex: 1,
});
The command respects lockPosition on the target column and lockPinnedColumns across pin zones.
Swap Two Columns
grid.commandBus.dispatch('column:swap', {
colIdA: 'name',
colIdB: 'email',
});
Swap directly exchanges two columns in the column array and emits column:moved.
Drag-and-Drop Behavior
When drag-and-drop is enabled, the plugin injects mousedown handlers on header cells. A 5px movement threshold distinguishes clicks from drags. During a drag:
- A floating ghost element appears near the cursor showing the column name.
- The cursor changes to
grabbing. - On mouse release over another header cell, the column is moved to that position.
// Columns with lockPosition cannot be dragged
const columns = [
{ colId: 'rowNum', field: 'rowNum', headerName: '#', lockPosition: true },
{ colId: 'name', field: 'name', headerName: 'Name' },
];
Commands
| Name | Payload | Description |
|---|---|---|
column:move |
{ colId: string; toIndex: number } |
Move a column to a specific index. Respects lockPosition and lockPinnedColumns. |
column:swap |
{ colIdA: string; colIdB: string } |
Swap the positions of two columns. |
column:dragStart |
{ colId: string; startX: number; startY?: number } |
Begin a drag interaction. Creates ghost element and attaches mouse listeners. |
Events
| Name | Payload | Description |
|---|---|---|
column:moved |
{ column: ColumnState; fromIndex: number; toIndex: number } |
Emitted after a column is moved or swapped. |
dom:headerRendered |
{} |
Listened to internally to re-inject drag handlers after header re-renders. |
grid:ready |
{} |
Listened to internally to inject drag handlers on initial mount. |
React Integration
import { GridStorm, useGridApi } from '@gridstorm/react';
import { ColumnReorderPlugin } from '@gridstorm/plugin-column-reorder';
function ReorderableGrid({ rowData, columns }) {
const apiRef = useGridApi();
const resetOrder = () => {
// Move columns back to original positions
columns.forEach((col, i) => {
apiRef.current?.commandBus.dispatch('column:move', {
colId: col.colId,
toIndex: i,
});
});
};
return (
<>
<button onClick={resetOrder}>Reset Column Order</button>
<GridStorm
rowData={rowData}
columns={columns}
plugins={[ColumnReorderPlugin()]}
/>
</>
);
}
Next Steps
- Column Pinning Plugin -- pin columns to edges (interacts with
lockPinnedColumns). - Column Resize Plugin -- resize handles coexist with drag handles on headers.
- Row Reorder Plugin -- reorder rows via drag-and-drop.