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

Headless usage

<GridLayout> is convenient, but it renders its own <div>s and class names. When you need full control of the markup — custom elements, your own placeholder, a bespoke drag preview — drop to the headless layer: SnapGridProvider plus a set of hooks.

Headless
your own markup via SnapGridProvider + hooks

The shape of it

SnapGridProvider owns the drag/resize session and exposes it through context. You render the container, the items, the placeholder, and the overlay yourself using the hooks.

import { SnapGridProvider, useGridContainer, useGridItem, useGridPlaceholder, GridDragOverlay, } from "@snapgridjs/react"; function Board({ layout, setLayout, width }) { return ( <SnapGridProvider layout={layout} width={width} onLayoutChange={setLayout}> <Surface items={layout} /> </SnapGridProvider> ); } function Surface({ items }) { const { containerProps } = useGridContainer(); const placeholder = useGridPlaceholder(); return ( <div {...containerProps}> {items.map((it) => ( <Tile key={it.i} id={it.i} /> ))} {placeholder && <div className="my-placeholder" style={placeholder.style} />} <GridDragOverlay>{(item) => <Tile id={item.i} preview />}</GridDragOverlay> </div> ); } function Tile({ id }) { const { ref, style, isDragging } = useGridItem(id); return ( <div ref={ref} style={style} data-dragging={isDragging}> {id} </div> ); }

The hooks

HookReturnsRenders
useGridContainer(){ containerProps, isDropTarget }The positioned surface; registers the droppable.
useGridItem(id){ ref, style, isDragging, item }A single tile, positioned and drag-wired.
useGridResizeHandle(id, axis){ ref, handleProps, isResizing }A resize handle for an edge/corner.
useGridPlaceholder(){ item, style } | nullThe landing-cell marker (null when idle).
useGridDragOverlay(){ item, style } | nullThe floating preview (source grid only).

Spread the returned ref / style / props onto your own elements. You choose the tag, the class names, and the cosmetics. snapgrid only supplies positioning and state.

The floating overlay is meant to be portaled to document.body so it can cross between grids unclipped. The <GridDragOverlay> convenience component does that for you; with the hook, render it in a portal yourself.

Mixing layers

The two layers share one engine, so you can use <GridLayout> for most of the app and the hooks for one special grid, or use <GridItem> inside your own surface. Nothing is all-or-nothing.

Last updated on