Skip to Content
snapgrid is a react-grid-layout v2 alternative built on dnd-kit. Drag, resize, repack, and drag between grids.
DocumentationGuidesCross-grid dragging

Cross-grid dragging

Wrap two or more grids in a <SnapGridGroup> and tiles can be dragged between them. The source grid loses the tile; the destination gains it. Each grid keeps its own controlled layout.

import { SnapGridGroup, GridLayout } from "@snapgridjs/react"; <SnapGridGroup> <GridLayout layout={left} width={w} onLayoutChange={setLeft} gridConfig={cfg}> {left.map((it) => <div key={it.i} className="tile">{it.i}</div>)} </GridLayout> <GridLayout layout={right} width={w} onLayoutChange={setRight} gridConfig={cfg}> {right.map((it) => <div key={it.i} className="tile">{it.i}</div>)} </GridLayout> </SnapGridGroup>;
Cross-grid dragging
drag a tile between the two grids

How it works

A standalone grid provides its own dnd-kit context. Inside a <SnapGridGroup>, all grids share one provider and a registry, so a drag that starts in one grid can be received by another. On drop:

  • the source grid removes the tile and fires its onLayoutChange with the tile gone;
  • the destination grid inserts the tile at the drop cell and fires its onLayoutChange with the tile added.

Both updates happen in the same gesture, each against its own layout state.

Item ids must be unique across every grid in a group. They share one drag manager. If two grids can hold an item with the same i, a cross-grid drop can’t tell them apart.

Callbacks

The destination grid signals a received tile through onLayoutChange only. It does not fire onDragStop, because it never fired onDragStart (the source grid owns the drag’s start/stop pair). Wire cross-grid persistence to onLayoutChange on both grids.

Dropping outside any grid

If a tile is dropped outside every grid in the group, the move reverts. The source keeps it and no onLayoutChange fires.

Last updated on