Skip to content

/web-dnd-dnd-kit

Drag and drop with @dnd-kit - draggable, droppable, sortable, collision detection, sensors, accessibility

shell
$ npx -y skills add agents-inc/skills --skill web-dnd-dnd-kit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/web-dnd-dnd-kit
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Drag and drop with @dnd-kit - draggable, droppable, sortable, collision detection, sensors, accessibility

SKILL.md

web-dnd-dnd-kit.SKILL.md
name: web-dnd-dnd-kit
description: Drag and drop with @dnd-kit - draggable, droppable, sortable, collision detection, sensors, accessibility

@dnd-kit Drag and Drop Patterns

> **Quick Guide:** Use `@dnd-kit/core` for basic drag/drop (`useDraggable`, `useDroppable`, `DndContext`). Use `@dnd-kit/sortable` for sortable lists (`useSortable`, `SortableContext`, `arrayMove`). Use `DragOverlay` for cross-container drag, scrollable containers, and smooth drop animations. Configure sensors for pointer/touch/keyboard input with activation constraints. Always provide keyboard and screen reader accessibility via `KeyboardSensor` and custom `announcements`.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST wrap all drag-and-drop content in a `<DndContext>` provider -- hooks only work inside DndContext)**

**(You MUST use `DragOverlay` when items move between containers or live in scrollable containers -- transform alone breaks in these cases)**

**(You MUST configure `KeyboardSensor` with `sortableKeyboardCoordinates` for sortable lists -- keyboard users cannot reorder without it)**

**(You MUST keep `DragOverlay` always mounted and conditionally render its children -- unmounting DragOverlay breaks drop animations)**

**(You MUST use named constants for all activation constraints, distances, and timing values -- NO magic numbers)**

</critical_requirements>

---

**Auto-detection:** @dnd-kit, dnd-kit, DndContext, useDraggable, useDroppable, useSortable, SortableContext, DragOverlay, useSensors, useSensor, PointerSensor, KeyboardSensor, closestCenter, closestCorners, rectIntersection, pointerWithin, arrayMove, sortableKeyboardCoordinates, CSS.Transform, @dnd-kit/core, @dnd-kit/sortable, @dnd-kit/utilities, @dnd-kit/modifiers

**When to use:**

  • Building sortable lists (reorderable todo, playlist, sidebar navigation)
  • Building Kanban boards with cross-container item movement
  • Implementing drag handles for specific activation areas
  • Creating droppable zones (file upload targets, trash bins, category bins)
  • Adding keyboard and screen reader accessible drag interactions

**When NOT to use:**

  • Simple reordering without drag UX (use array manipulation + buttons instead)
  • Drag interactions that only need native HTML5 drag-and-drop (e.g., file drops from OS)
  • Complex physics-based drag (consider a gesture/spring animation library instead)

**Key patterns covered:**

  • DndContext + useDraggable + useDroppable for basic drag/drop
  • SortableContext + useSortable + arrayMove for sortable lists
  • DragOverlay for cross-container drag and smooth animations
  • Sensor configuration (pointer, touch, keyboard) with activation constraints
  • Collision detection strategies (closestCenter, closestCorners, pointerWithin, rectIntersection)
  • Sorting strategies (vertical, horizontal, rect/grid)
  • Keyboard and screen reader accessibility
  • Multi-container sortable (Kanban boards)
  • Modifiers for axis locking and boundary constraints

---

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - DndContext, useDraggable, useDroppable, useSortable, sensors, collision detection, accessibility
  • [examples/advanced.md](examples/advanced.md) - Multi-container Kanban, DragOverlay, modifiers, custom collision detection
  • [reference.md](reference.md) - Decision frameworks, API quick reference, sorting strategies, anti-patterns

---

<philosophy>

Philosophy

@dnd-kit is a modular, lightweight drag-and-drop toolkit for React built around hooks. It separates concerns into focused packages: `@dnd-kit/core` for the drag/drop primitives, `@dnd-kit/sortable` for list reordering, `@dnd-kit/utilities` for CSS transform helpers, and `@dnd-kit/modifiers` for movement constraints.

**Core principles:**

1. **Hooks-first** -- `useDraggable`, `useDroppable`, and `useSortable` keep drag logic colocated with components 2. **Sensor-driven input** -- Pointer, touch, and keyboard inputs are separate sensor plugins, not hardcoded behavior 3. **Collision detection is pluggable** -- Choose the right algorithm for your layout (list vs grid vs stacked containers) 4. **Accessibility by default** -- Built-in ARIA attributes, keyboard navigation, and screen reader announcements 5. **No DOM manipulation** -- Uses CSS transforms for positioning, not DOM reordering during drag

**Package overview:**

| Package | Purpose | |---------|---------| | `@dnd-kit/core` | DndContext, useDraggable, useDroppable, DragOverlay, sensors, collision detection | | `@dnd-kit/sortable` | SortableContext, useSortable, sorting strategies, arrayMove, sortableKeyboardCoordinates | | `@dnd-kit/utilities` | CSS.Transform.toString, CSS.Transition.toString | | `@dnd-kit/modifiers` | restrictToVerticalAxis, restrictToHorizontalAxis, restrictToParentElement, restrictToWindowEdges |

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Basic Drag and Drop

`DndContext` is the provider that connects draggable and droppable elements. `useDraggable` makes an element draggable. `useDroppable` makes an element a drop target.

import { DndContext, type DragEndEvent } from "@dnd-kit/core";

function App() {
  const [parent, setParent] = useState<string | null>(null);

  function handleDragEnd(event: DragEndEvent) {
    const { over } = event;
    setParent(over ? String(over.id) : null);
  }

  return (
    <DndContext onDragEnd={handleDragEnd}>
      <DraggableItem id="item-1" />
      <DroppableZone id="zone-a">{parent === "zone-a" && <span>Dropped here</span>}</DroppableZone>
    </DndContext>
  );
}

**Why good:** DndContext wraps all participants, event handler updates state on drop, draggable and droppable use unique string IDs

See [examples/core.md](examples/core.md) Pattern 1 for full useDraggable and useDroppable implementations with TypeScript types.

---

Pattern 2:

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked