Svelte
gridla/svelte is the Svelte 5 adapter: the same headless components as gridla/react, written with runes. GridProvider owns layout and gesture state, GridCanvas measures itself and wires pointer and keyboard input, GridItem positions one item, and GridPreviewOutline shows where the active item will land. Appearance is yours. It is a thin binding over gridla/interaction, the same layer the React adapter is built on, so behavior is identical across adapters.
Appearance is yours: see the styling guide for every data-gridla-* attribute, resize handle sizing, the preview outline, and a starter stylesheet.
Install
svelte (5 or later) is an optional peer dependency. The adapter ships as Svelte source (.svelte components and .svelte.ts modules under dist/svelte/) with a svelte export condition, so Vite, SvelteKit, and Rsbuild compile it with the rest of your app.
Minimal example
What each piece does:
GridProviderholds the source layout, projects it onto the measured canvas size (responsiveistrueby default), and runs the solvers during gestures.gap,snapDistance,snap, andonTraceare the sameSolveOptionsthe core takes.GridCanvasrenders adivwithposition: relative, measures itself withResizeObserver, and attaches the pointer and keyboard listeners. Give it a height.GridItemrenders adivpositioned withtransformand setsdata-gridla-active,data-gridla-selected, anddata-gridla-shiftedfor styling.resizeEdgesadds built-in resize handles. Its children snippet receives the item view, so content can react toisSelected,rect, and the rest.GridPreviewOutlinerenders a box where the active item will land when released, and nothing when there is no gesture.
Render the items from a stable list of ids (here the initial layout): each GridItem follows its own geometry through a rune, so the list itself does not update during a drag.
Controlled and uncontrolled
layout is bindable. Bind it to keep the state yourself: every accepted change lands in your variable, and assigning a new layout to it re-renders the canvas.
onLayoutChange fires with the next layout and a GridChangeDetail (reason, itemId, strategy) after every accepted change, bound or not. Passing layout without bind: works too: the provider updates the layout it renders and reports the change, and the next value you pass wins. Use defaultLayout when you only need the initial state. See controlled state and persistence.
Nested layouts and transfers
A nested canvas is a GridProvider inside a GridItem. Wrap the providers in one GridTransferScope and items move between them: the pointer decides the target, the target previews the drop, and releasing commits it. onTransferOut fires on the source, onTransferIn on the target, and both bound layouts follow.
draggable={false} turns off the whole-item drag surface so the nested canvas can receive pointer input; view.dragHandleProps marks the header as the group's handle. acceptTransfers takes a boolean or a predicate. See the transfer recipe for the rules the scope applies.
Runes
The module exports rune-style readers. Call them during component initialization (they read the provider from context) and read .current wherever you need the value; it tracks like any rune.
gridActions() returns the same imperative API as the other adapters (move, resize, place, remove, update, select, setLayout, cancel, and the incoming-preview trio); place, move, and resize return false when the solver rejected the request.
Server rendering and SvelteKit
The adapter touches window and document only inside effects, so it renders on the server. The server output is the authored layout: items sit where the layout puts them, in the layout's own pixels, and the canvas takes the layout size when responsive is off. On the client, GridCanvas measures itself in an effect before the first paint completes and the provider projects the layout onto the measured size, so hydration does not flash an unprojected layout for longer than a frame. Nothing else is needed for SvelteKit; keep ssr on and render the components as usual.
Styling
Items and the preview are unstyled divs. A minimal stylesheet:
API
The full reference, generated from the source declarations, is under API › Svelte.
Next
- Custom rendering: drag handles and your own resize chrome; the render-prop patterns map onto the children snippet.
- Keyboard controls: what the built-in handlers do and how to extend them.
- Multiple canvases: transfer scopes in depth.