> ## Documentation Index
> Fetch the complete documentation index at: https://dndkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Droppable

> Create droppable targets for draggable elements.

export const Story = ({id, framework = "react", width = "100%", height = "250", hero = false}) => {
  const BRANCH = 'experimental';
  const STORYBOOKS = {
    react: {
      localPort: 6006,
      productionHost: '5fc05e08a4a65d0021ae0bf2'
    },
    vue: {
      localPort: 6008,
      productionHost: '6989440ed560d70abcd6bcc7'
    },
    vanilla: {
      localPort: 6007,
      productionHost: '69892d294eb9040f0d29aa81'
    },
    solid: {
      localPort: 6009,
      productionHost: '698944444eb9040f0d2a0217'
    },
    svelte: {
      localPort: 6010,
      productionHost: '69910d2a631cb57638616dcd'
    }
  };
  const config = STORYBOOKS[framework] ?? STORYBOOKS.react;
  const isDev = import.meta.env.DEV;
  const host = isDev ? `//localhost:${config.localPort}` : `https://${BRANCH}--${config.productionHost}.chromatic.com`;
  return <Frame>
      <iframe src={`${host}/iframe.html?args=&id=${id}&viewMode=story&hero=${hero}`} width={width} height={height} />
    </Frame>;
};

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

## Usage

The `Droppable` class creates drop targets that can receive [draggable](/concepts/draggable) elements. First, create a [DragDropManager](/concepts/drag-drop-manager) instance:

```js theme={null}
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 `accept` property. See the [draggable types](/concepts/draggable#types) documentation for more details.

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

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

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

## Collision Detection

By default, the `Droppable` class uses the `defaultCollisionDetection` algorithm from `@dnd-kit/collision`: it first checks whether the pointer is over the drop target, and falls back to rectangle intersection when there is no pointer collision (for example, during keyboard-driven drags):

<img src="https://mintcdn.com/dnd-kit/rEYJHsL1jSwxik0X/images/droppable/shape-intersection.svg?fit=max&auto=format&n=rEYJHsL1jSwxik0X&q=85&s=6104b44ae324a38997f2b29fe65746cb" alt="Rectangle intersection collision detection" width="1085" height="414" data-path="images/droppable/shape-intersection.svg" />

You can customize this behavior with different collision detection algorithms:

```js theme={null}
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:

<img src="https://mintcdn.com/dnd-kit/rEYJHsL1jSwxik0X/images/droppable/closest-center.svg?fit=max&auto=format&n=rEYJHsL1jSwxik0X&q=85&s=e061fa864df8c1a35805bab0b1a97f79" alt="Closest center collision detection" width="1238" height="923" data-path="images/droppable/closest-center.svg" />

### 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 theme={null}
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="accept" type="Type | Type[] | ((source: Draggable) => boolean)">
  Restrict which draggables can be dropped on this target. Pass a single [`type`](#param-type), an array of types, or a predicate that receives the draggable and returns `true` to accept it. If omitted, every draggable is accepted. See [accepting specific types](#accepting-specific-types) for more details.
</ParamField>

<ParamField path="type" type="string | number | Symbol">
  An optional identifier to categorize this droppable. Whether a draggable can be dropped on this target is determined by this droppable's own [`accept`](#param-accept) rule checked against the **draggable's** `type` — a droppable's `type` is not consulted by `accept` rules.
</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:

  * `defaultCollisionDetection`: Default, uses pointer intersection with a fallback to rectangle intersection
  * `shapeIntersection`: 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
