Back to home

Draggable Example

Demonstrates the Draggable component: wrap a single child element and drag it freely with @dnd-kit.

Sandbox

Three independent draggable cards. Each Draggable owns its own DndContext, so they don't interfere.

Card A
Card B
Card C

Typical usage

Wrap any single element — a div, a button — in Draggable to make it movable.

Grab and drag the button to move it around.

Draggable Component Usage Guide

Overview

src/common/components/Draggable.tsx turns any single child element into a draggable object, built on @dnd-kit/core: position is stored in useState, dragging is captured by useDraggable + MouseSensor (activates after 5px of movement), and onDragEnd accumulates the delta.

Basic usage

import Draggable from "@/common/components/Draggable";

<Draggable>
  <div className="rounded-lg border px-4 py-2">Drag me</div>
</Draggable>
PropTypeRequiredDescription
childrenReact.ReactNodeYesThe child to drag; must be a single element (uses React.Children.only)
asChildbooleanNoReserved; currently always merges drag props into the child

How it works

  • useDraggable provides listeners (onPointerDown, ...), attributes (role / aria-*), setNodeRef and transform.
  • DraggableContainer merges these — plus ref and style (transform + cursor) — onto the child via AsChild.
  • While dragging, transform is the relative offset of the current drag, added on top of the committed position; onDragEnd adds the delta back into position.

Notes

  • Style the child with className — not inline style, or you will clobber the injected transform.
  • Each Draggable owns its own DndContext, so multiple instances coexist without interfering.
  • The drag id is currently hard-coded to "box"; to manage multiple draggables under one DndContext, switch to a dynamic id.