Back to Dnd Kit

Droppable

apps/docs/concepts/droppable.mdx

latest5.5 KB
Original Source

import {Story} from '/snippets/story.mdx';

<Story id="droppable-basic-setup--example" framework="vanilla" height="400" hero />

Usage

The Droppable class creates drop targets that can receive draggable elements. First, create a DragDropManager instance:

js
import {Droppable, DragDropManager} from '@dnd-kit/dom';

const manager = new DragDropManager();

const element = document.createElement('div');
element.classList.add('droppable');

// Create a droppable target
const droppable = new Droppable({
  id: 'drop-zone',
  element,
}, manager);

document.body.appendChild(element);

// Listen for drop events
manager.monitor.addEventListener('dragend', (event) => {
  if (event.operation.target?.id === droppable.id) {
    console.log('Item dropped!', event.operation.source);
  }
});

Accepting Specific Types

You can restrict which draggable elements can be dropped by using the accepts property. See the draggable types documentation for more details.

js
// Accept only draggables with type 'item'
const droppable = new Droppable({
  id: 'drop-zone',
  element,
  accepts: 'item'
}, manager);

// Accept multiple types
const droppable = new Droppable({
  id: 'drop-zone',
  element,
  accepts: ['item', 'card']
}, manager);

// Use a function for custom logic
const droppable = new Droppable({
  id: 'drop-zone',
  element,
  accepts: (draggable) => {
    // Custom acceptance logic
    return draggable.type === 'item' && draggable.data.category === 'fruit';
  }
}, manager);

Collision Detection

By default, the Droppable class uses rectangle intersection to detect when draggable elements are over the drop target:

You can customize this behavior with different collision detection algorithms:

js
import {
  closestCenter,
  pointerIntersection,
  directionBiased
} from '@dnd-kit/collision';

// Use closest center point for card stacking
const droppable = new Droppable({
  id: 'card-stack',
  element,
  collisionDetector: closestCenter
}, manager);

For example, the closestCenter detector will detect collisions based on the distance between the center points, which is ideal for card stacking:

Collision Priority

When multiple droppable targets overlap, you can set priority to determine which one should receive the drop. This is particularly useful for nested containers:

js
const container = new Droppable({
  id: 'container',
  element: containerElement,
  collisionPriority: 1 // Lower priority
}, manager);

const item = new Droppable({
  id: 'item',
  element: itemElement,
  collisionPriority: 2 // Higher priority
}, manager);

API Reference

Arguments

The Droppable class accepts the following arguments:

<ParamField path="id" type="string | number" required> A unique identifier for this droppable target within the same [drag and drop context provider](/concepts/drag-drop-manager). </ParamField> <ParamField path="element" type="Element"> The DOM element to make droppable. While not required in the constructor, it must be set to enable dropping. </ParamField> <ParamField path="accepts" type="string | number | Symbol | ((draggable: Draggable) => boolean)"> Specify which draggable elements can be dropped on this target. See [accepting specific types](#accepting-specific-types) for more details. </ParamField> <ParamField path="collisionDetector" type="CollisionDetector"> A function to determine when draggable elements are over this target. See [collision detection](#collision-detection) for built-in options, such as: - `shapeIntersection`: Default, uses rectangle intersection - `pointerIntersection`: Uses pointer position for precise detection - `closestCenter`: Uses center point distance, ideal for card stacking - `directionBiased`: Considers drag direction, useful for sortable lists </ParamField> <ParamField path="collisionPriority" type="number"> Priority level when multiple droppable targets overlap. Higher numbers take precedence. See [collision priority](#collision-priority) for more details. </ParamField> <ParamField path="disabled" type="boolean"> Set to `true` to temporarily prevent dropping on this target. </ParamField> <ParamField path="data" type="{[key: string]: any}"> Optional data to associate with this droppable target, available in event handlers. </ParamField> <ParamField path="effects" type="() => Effect[]"> <Info>This is an advanced feature and should not need to be used by most consumers.</Info> You can supply a function that returns an array of reactive effects that can be set up and automatically cleaned up when invoking the `destroy()` method of this instance. </ParamField>

Properties

The Droppable instance provides these key properties:

  • id: The unique identifier
  • element: The DOM element acting as the drop target
  • disabled: Whether dropping is currently disabled
  • isDropTarget: Whether a draggable is currently over this target
  • shape: The current bounding shape of the drop target

Methods

  • accepts(draggable): Check if this target accepts a draggable element
  • refreshShape(): Recalculate the target's dimensions
  • register(): Register this target with the manager
  • unregister(): Remove this target from the manager
  • destroy(): Clean up this droppable instance and remove all listeners