Changelog
All notable changes to this project are documented here. The format is based on Keep a Changelog , and the project aims to follow Semantic Versioning from 1.0 onward.
0.7.0 - 2026-06-10
The tile hooks now speak the dnd-kit options-object idiom, and snapMove reads the destination
grid’s geometry for you — interop onDragOver handlers get noticeably smaller.
Changed
useGridItem/useGridResizeHandletake an options object (@snapgridjs/react, BREAKING) —useGridItem({ id, group }),useGridResizeHandle({ id, handle, group })— mirroring dnd-kit’suseSortable. Move positional call sites to objects.snapMoveresolves the destination grid (@snapgridjs/dnd, re-exported from@snapgridjs/react). It readspositionParams, the compactor, and the default item size from the grid under the pointer (event.operation.target), so an interoponDragOverno longer rebuildsPositionParamsby hand — everySnapMoveContextfield is now an optional override. A foreign source’ssnapGridDropspec (size + id) is honored, matching the external-drop path.
Added
- Customizable
typeonuseGridItem(the tile’s sortabletype) anduseGridContainer(the surface’s droppabletype) — default"grid-item"/"grid"— to namespace tiles and grids for ecosystem interop. The grid identifies its own tiles by their payload, not the type string, so a custom type still drags and crosses grids.
0.6.1 - 2026-06-07
Fixed
@snapgridjs/dnd: a grid’s landing placeholder could linger over the sortable when a tile was dragged out to a foreign dnd-kituseSortablelist. Once the dragged element is swapped for the foreign card mid-drag, the engine’s external-source path now clears the source grid’s placeholder too (it previously only cleared on the in-grid move path, so it surfaced intermittently).
0.6.0 - 2026-06-07
A grid now interoperates with the wider dnd-kit ecosystem, not just other grids: drag a
useSortable card into a grid, a tile back out, or reorder the list — all in one drag, under one
provider.
Added
- dnd-kit sortable interop.
snapMove(layout, event, ctx)(@snapgridjs/dnd, re-exported from@snapgridjs/react) places a dragged item into a gridLayoutat the pointer cell, with compaction — call it from your ownonDragOver.removeItemWithCompactoris the drag-out counterpart, now re-exported from@snapgridjs/reactalongsideinsertItemWithCompactor,toPositionParams, anddefaultGridConfig. See the new dnd-kit interop guide. acceptoption onuseGridContainer/<GridLayout>— opt a foreign dnd-kit sortable in as a drop target (you drive the receive inonDragOver).
Changed
- Grid tiles now position with
left/topinstead of atransform, so dnd-kit’s self-float reads each tile’s true rect when it’s handed off to a sortable list. Reflow still animates on the compositor (a transform FLIP). Spread thestylefromuseGridItemas before and don’t override the position. - Grid collision is now pointer-based: a grid claims a drag while the pointer is inside it, rather than while the dragged tile’s rectangle overlaps it — letting a tile leave a grid for an adjacent sortable, and matching the pointer-based receive math.
0.5.0 - 2026-06-06
The dnd-kit engine is extracted into a new package, @snapgridjs/dnd — the drag/resize/cross-grid
brain is now framework-agnostic and reusable. For React users the upgrade is transparent.
Added
@snapgridjs/dnd— the framework-agnostic dnd-kit engine@snapgridjs/reactis built on: one per-manager drag/resize/cross-grid engine, the observableGridControllerrender bridge, the collision detector, sensors, and the snap-to-grid modifier. It exists so future Vue/Solid/Svelte bindings can share one engine. See the new Architecture & dnd-kit guide.
Changed
@snapgridjs/reactis now a thin binding over@snapgridjs/dnd. For React consumers this is transparent — the public API is unchanged (drag/drop config and event types are still exported from@snapgridjs/react, re-exported from the engine package).- One engine per dnd-kit manager now drives every grid (previously one monitor per grid), so a multi-grid page processes each drag event once.
- All four packages —
@snapgridjs/core,@snapgridjs/dnd,@snapgridjs/react,@snapgridjs/extras— now release together in lockstep.
0.4.0 - 2026-06-05
Nested grids gain cross-level dragging, and all packages now move in lockstep on one version.
Added
@snapgridjs/react: nested grids share one provider and support cross-level dragging. A grid inside another tile shares the outerDragDropProvider; collision resolves the innermost grid under the pointer, so a drag stays scoped to the inner grid until you drag a tile out, and tiles move between levels. A grid won’t accept a source that contains it. Keep a nested grid self-contained by giving it its ownDragDropProvider.
Fixed
@snapgridjs/core: a tile received from another grid (cross-grid or nested) couldn’t land in an occupied row — e.g. the target grid’s top row. It now displaces the occupant, matching a same-grid drop.
Changed
@snapgridjs/core,@snapgridjs/react, and@snapgridjs/extrasnow share one version and are released together (lockstep), so a given version number is always a matched set.
0.3.0 - 2026-06-04
Pinned tiles — a static item can opt back into user interaction.
Added
@snapgridjs/react: astaticitem that also setsisDraggable: truestays anchored against compaction (others flow around it) yet can still be dragged by the user — a “pinned” tile.isResizable: truedoes the same for resizing. A plainstaticitem stays fully locked as before.
Changed
@snapgridjs/extras: thegravity/masonry/shelfpackers now honorstaticplacement (statics are reserved in place and movable items pack around them), matching the built-in compactors.
0.2.0 - 2026-06-04
The headless layer is rebuilt to be dnd-kit–native. A dragged tile now floats itself (dnd-kit’s
default feedback) instead of being mirrored by a separate overlay, and a grid composes into a
DragDropProvider you supply rather than minting its own. This is a breaking change to the headless
API only — the turnkey <GridLayout> / <SnapGridGroup> components still supply the provider for you
and are unaffected.
Changed
- Breaking —
@snapgridjs/react:SnapGridProvideris removed. Render inside a dnd-kitDragDropProviderand host the grid with the newuseGridContainer(options)hook (returns{ containerProps, group, isDropTarget, controller }); tiles resolve their grid bygroup. useGridItem(id, group)is now a real dnd-kituseSortable, so tiles interoperate with the dnd-kit sortable ecosystem.- Drop targets resolve through dnd-kit’s collision system — one oracle drives both the move preview and the drop, making cross-grid and external drops more robust.
snapToGridis now implemented as a dnd-kitModifier(still toggled viadragConfig.snapToGrid).
Added
useGridItemexposes an optionalhandleReffor wiring a drag handle.- Live drag state lives in an observable
GridController, so a drag re-renders only the tiles whose cell actually changed. - dnd-kit’s raw
DragOverlayis re-exported as an escape hatch for a custom floating preview.
Removed
- Breaking —
@snapgridjs/react:GridDragOverlay,useGridDragOverlay, anddragOverlayStyle. A dragged tile floats itself, so there is no overlay to render.
0.1.0 - 2026-05-31
Initial public release.
Added
@snapgridjs/react: controlledGridLayout,ResponsiveGridLayout,GridItem,GridPlaceholder,GridDragOverlay, and the headlessSnapGridProvider+ hooks.SnapGridGroupfor dragging tiles between grids; external-drop support viadropConfig/onDrop.@snapgridjs/extras:masonry,gravity,shelfpackers (pluswrapand fast compactors).useContainerWidth,useResponsiveLayout, and opt-in grid snapping (dragConfig.snapToGrid).- Keyboard dragging: focus a tile, Enter/Space to pick up, arrow keys to move a cell at a time, Enter/Space to drop, Escape to cancel.
- Documentation site (
apps/docs) with guides, API reference, and live examples — including a nested-grids guide and a real-world showcase dashboard.