Skip to content
Apps— browse docs
On this page

Step 4: Drag a block

A pointer handler and one write — actions.map("blocks").set — and the block stays where you leave it.

Reading data.blocks was step 3. Now write to it. Add a pointer handler that turns a drag into actions.map("blocks").set(key, position):

const begin = (i: number, e: PointerEvent) => {
  /* remember where inside the block the pointer grabbed it */
}
const onMove = (e: PointerEvent) => {
  actions.map("blocks").set(String(i), { x, y }) // ← the whole sync layer
}
Make it draggable
src/app.tsx

Edit and the example re-runs. Tab indents; press Escape to leave the editor.

Running · your edits, live
Starting the example…

You should see: drag a letter and it stays exactly where you drop it — even after the debounce re-runs the example, even if you drag two letters back to back. field.map is keyed per block, so two people dragging different letters both land clean; the same rule Step 3 of Getting Started used for notes.

Note:

Why this doesn't flood the document on every pixel

It does write on every pointermove here, and for a 3-letter word that's fine. The published Blocks kit batches with requestAnimationFrame instead — worth doing once a drag gesture gets busy. The Blocks starter kit has the full breakdown, plus rotate, scale, and a tumble-to-a-new-face gesture this page skips.

Next steps