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

# DragDropManager

> Orchestrate drag and drop interactions between elements.

The `DragDropManager` is the central orchestrator of the drag and drop system. It coordinates all interactions between draggable and droppable elements.

<svg viewBox="0 0 776 534" style={{maxWidth: '776px'}} class="not-prose" xmlns="http://www.w3.org/2000/svg" width="100%" id="ddm-flowchart">
  <style>
    {"#ddm-flowchart{font-family:inherit;font-size:16px;fill:#555;}#ddm-flowchart p{margin:0;}#ddm-flowchart .node rect{fill:#f5f6fa;stroke:#d0d1d5;stroke-width:1px;}#ddm-flowchart span{fill:#555;color:#555;}#ddm-flowchart .link{stroke:#d0d1d5;stroke-width:2px;fill:none;}#ddm-flowchart .arrow{fill:#a1a1a6;stroke:#a1a1a6;}#ddm-flowchart .edge-label{text-align:center;}#ddm-flowchart .edge-label p{background-color:white;}#ddm-flowchart .node-primary rect{fill:rgba(89,109,255,0.12);stroke:rgba(89,109,255,0.4);}#ddm-flowchart .node-primary span{fill:#596dff;color:#596dff;}#ddm-flowchart .node-cell{display:flex;align-items:center;justify-content:center;gap:8px;height:100%;}#ddm-flowchart .node-cell img{width:14px;height:14px;opacity:0.3;flex-shrink:0;}#ddm-flowchart .node-primary .node-cell img{opacity:0.5;}.dark #ddm-flowchart{fill:#ccc;}.dark #ddm-flowchart .node rect{fill:#1f2020;stroke:#555;}.dark #ddm-flowchart span{fill:#ccc;color:#ccc;}.dark #ddm-flowchart .link{stroke:#555;}.dark #ddm-flowchart .arrow{fill:#888;stroke:#888;}.dark #ddm-flowchart .edge-label p{background-color:#0b0b10;}.dark #ddm-flowchart .node-cell img{filter:invert(1);}.dark #ddm-flowchart .node-primary rect{fill:rgba(89,109,255,0.15);stroke:rgba(89,109,255,0.5);}.dark #ddm-flowchart .node-primary span{fill:#93a2ff;color:#93a2ff;}"}
  </style>

  <defs>
    <marker orient="auto" markerHeight="8" markerWidth="8" markerUnits="userSpaceOnUse" refY="5" refX="5" viewBox="0 0 10 10" id="ddm-arrow">
      <path class="arrow" d="M 0 0 L 10 5 L 0 10 z" />
    </marker>
  </defs>

  <g>
    <path markerEnd="url(#ddm-arrow)" class="link" d="M441.32,62L441.32,66.167C441.32,70.333,441.32,78.667,441.32,86.333C441.32,94,441.32,101,441.32,104.5L441.32,108" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M380.309,150.749L345.471,157.457C310.633,164.166,240.957,177.583,206.119,187.791C171.281,198,171.281,205,171.281,208.5L171.281,212" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M397.615,166L390.87,170.167C384.125,174.333,370.636,182.667,363.891,190.333C357.146,198,357.146,205,357.146,208.5L357.146,212" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M485.026,166L491.771,170.167C498.515,174.333,512.005,182.667,518.749,190.333C525.494,198,525.494,205,525.494,208.5L525.494,212" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M502.332,151.174L535.598,157.812C568.864,164.449,635.396,177.725,668.662,187.862C701.928,198,701.928,205,701.928,208.5L701.928,212" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M525.494,270L525.494,276.167C525.494,282.333,525.494,294.667,533.455,306.609C541.415,318.55,557.336,330.101,565.296,335.876L573.257,341.651" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M613.711,398L613.711,404.167C613.711,410.333,613.711,422.667,613.711,434.333C613.711,446,613.711,457,613.711,462.5L613.711,468" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M701.928,270L701.928,276.167C701.928,282.333,701.928,294.667,693.967,306.609C686.007,318.55,670.086,330.101,662.126,335.876L654.165,341.651" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M211.022,270L220.098,276.167C229.175,282.333,247.327,294.667,256.404,306.333C265.48,318,265.48,329,265.48,334.5L265.48,340" />

    <path markerEnd="url(#ddm-arrow)" class="link" d="M131.541,270L122.464,276.167C113.388,282.333,95.235,294.667,86.159,306.333C77.082,318,77.082,329,77.082,334.5L77.082,340" />

    <g transform="translate(525.494, 307)" class="edge-label"><foreignObject height="24" width="92" x="-46" y="-12"><div style={{display: 'table-cell', whiteSpace: 'nowrap', lineHeight: 1.5, maxWidth: '200px', textAlign: 'center'}} xmlns="http://www.w3.org/1999/xhtml"><p>Detect input</p></div></foreignObject></g>
    <g transform="translate(613.711, 435)" class="edge-label"><foreignObject height="24" width="55" x="-27" y="-12"><div style={{display: 'table-cell', whiteSpace: 'nowrap', lineHeight: 1.5, maxWidth: '200px', textAlign: 'center'}} xmlns="http://www.w3.org/1999/xhtml"><p>Trigger</p></div></foreignObject></g>
    <g transform="translate(701.928, 307)" class="edge-label"><foreignObject height="24" width="78" x="-39" y="-12"><div style={{display: 'table-cell', whiteSpace: 'nowrap', lineHeight: 1.5, maxWidth: '200px', textAlign: 'center'}} xmlns="http://www.w3.org/1999/xhtml"><p>Transform</p></div></foreignObject></g>

    <g transform="translate(441.32, 35)" class="node node-primary"><rect height="54" width="127" y="-27" x="-63.5" rx="4" /><foreignObject height="54" width="127" x="-63.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/sitemap.svg" /><p>Manager</p></div></foreignObject></g>
    <g transform="translate(441.32, 139)" class="node"><rect height="54" width="122" y="-27" x="-61" rx="4" /><foreignObject height="54" width="122" x="-61" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/database.svg" /><p>Registry</p></div></foreignObject></g>
    <g transform="translate(171.28, 243)" class="node"><rect height="54" width="115" y="-27" x="-57.5" rx="4" /><foreignObject height="54" width="115" x="-57.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/layer-group.svg" /><p>Entities</p></div></foreignObject></g>
    <g transform="translate(357.15, 243)" class="node"><rect height="54" width="115" y="-27" x="-57.5" rx="4" /><foreignObject height="54" width="115" x="-57.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/cube.svg" /><p>Plugins</p></div></foreignObject></g>
    <g transform="translate(525.49, 243)" class="node"><rect height="54" width="122" y="-27" x="-61" rx="4" /><foreignObject height="54" width="122" x="-61" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/monitor-waveform.svg" /><p>Sensors</p></div></foreignObject></g>
    <g transform="translate(701.93, 243)" class="node"><rect height="54" width="131" y="-27" x="-65.5" rx="4" /><foreignObject height="54" width="131" x="-65.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/sliders.svg" /><p>Modifiers</p></div></foreignObject></g>
    <g transform="translate(77.08, 371)" class="node"><rect height="54" width="138" y="-27" x="-69" rx="4" /><foreignObject height="54" width="138" x="-69" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/bullseye-pointer.svg" /><p>Draggable</p></div></foreignObject></g>
    <g transform="translate(265.48, 371)" class="node"><rect height="54" width="139" y="-27" x="-69.5" rx="4" /><foreignObject height="54" width="139" x="-69.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/expand.svg" /><p>Droppable</p></div></foreignObject></g>
    <g transform="translate(613.71, 371)" class="node"><rect height="54" width="135" y="-27" x="-67.5" rx="4" /><foreignObject height="54" width="135" x="-67.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/arrow-pointer.svg" /><p>Operation</p></div></foreignObject></g>
    <g transform="translate(613.71, 499)" class="node"><rect height="54" width="111" y="-27" x="-55.5" rx="4" /><foreignObject height="54" width="111" x="-55.5" y="-27"><div class="node-cell" xmlns="http://www.w3.org/1999/xhtml"><img src="https://d3gk2c5xim1je2.cloudfront.net/v7.1.0/regular/signal-stream.svg" /><p>Events</p></div></foreignObject></g>
  </g>
</svg>

## Usage

Create a manager instance to coordinate drag and drop interactions:

```js theme={null}
import {DragDropManager} from '@dnd-kit/dom';

const manager = new DragDropManager();
```

<ParamField path="options" type="object">
  Optional configuration for the manager:

  * `sensors`: [Sensors](/extend/sensors) to detect drag interactions — an array or a function that receives the defaults
  * `plugins`: [Plugins](/extend/plugins) to extend functionality — an array or a function that receives the defaults
  * `modifiers`: [Modifiers](/extend/modifiers) to customize behavior — an array or a function that receives the defaults
</ParamField>

## Configuration

The manager comes with sensible defaults, but you can customize its behavior. The `plugins`, `sensors`, and `modifiers` options accept either an array (which replaces the defaults) or a function that receives the default values and returns a new array.

### Extending defaults

Use the function form to add to or configure the defaults without replacing them:

```js theme={null}
import {
  DragDropManager,
  PointerSensor,
  PointerActivationConstraints,
} from '@dnd-kit/dom';
import {RestrictToWindow} from '@dnd-kit/dom/modifiers';

const manager = new DragDropManager({
  // Add a plugin to the defaults
  plugins: (defaults) => [...defaults, MyPlugin],

  // Configure a default sensor
  sensors: (defaults) => [
    ...defaults,
    PointerSensor.configure({
      activationConstraints: [
        new PointerActivationConstraints.Distance({value: 5}),
      ],
    }),
  ],

  // Add a modifier
  modifiers: (defaults) => [...defaults, RestrictToWindow],
});
```

### Replacing defaults

Pass an array to fully replace the defaults:

```js theme={null}
import {
  DragDropManager,
  KeyboardSensor,
  PointerSensor,
} from '@dnd-kit/dom';

const manager = new DragDropManager({
  sensors: [
    PointerSensor,  // Handles mouse and touch
    KeyboardSensor, // Enables keyboard navigation
  ],

  plugins: [
    AutoScroller,   // Automatic scrolling during drag
    Accessibility,  // ARIA attributes management
  ],

  modifiers: [
    RestrictToWindow, // Keeps dragged items within window bounds
  ],
});
```

<AccordionGroup>
  <Accordion title="Default configuration">
    The manager includes these defaults out of the box:

    **Sensors**

    * `PointerSensor`: Handles mouse and touch interactions
      * Mouse: Activates immediately on drag handle
      * Touch: 250ms delay with 5px movement tolerance
      * Other pointers: 200ms delay with 5px distance threshold
    * `KeyboardSensor`: Enables keyboard navigation with arrow keys

    **Plugins**

    * `Accessibility`: Manages ARIA attributes and announcements
    * `AutoScroller`: Scrolls containers when dragging near edges
    * `Cursor`: Updates cursor appearance during drag
    * `Feedback`: Controls visual feedback during drag
    * `PreventSelection`: Prevents text selection while dragging
    * `ScrollListener`: Monitors scroll events during drag
    * `Scroller`: Handles programmatic scrolling
  </Accordion>
</AccordionGroup>

## Events

The manager's `monitor` lets you observe drag and drop events:

```js theme={null}
// Observe drag start
manager.monitor.addEventListener('beforedragstart', (event) => {
  // Optionally prevent dragging
  if (shouldPreventDrag(event.operation.source)) {
    event.preventDefault();
  }
});

// Track movement
manager.monitor.addEventListener('dragmove', (event) => {
  const {source, position} = event.operation;
  console.log(`Dragging ${source.id} to ${position.current}`);
});

// Detect collisions
manager.monitor.addEventListener('collision', (event) => {
  const [firstCollision] = event.collisions;
  if (firstCollision) {
    console.log(`Colliding with ${firstCollision.id}`);
  }
});

// Listen for when dragging ends
manager.monitor.addEventListener('dragend', (event) => {
  const {source, target, canceled} = event.operation;
  if (!canceled && target) {
    console.log(`Dropped ${source.id} onto ${target.id}`);
  }
});
```

### Available Events

<ResponseField name="beforedragstart" type="Event">
  Fires before drag begins. Can be prevented.

  <Expandable title="Properties">
    <ResponseField name="operation" type="object">
      The drag operation that is about to begin
    </ResponseField>

    <ResponseField name="preventDefault" type="function">
      Call to prevent the drag operation from starting
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="dragstart" type="Event">
  Fires when drag starts.

  <Expandable title="Properties">
    <ResponseField name="operation" type="object">
      The current drag operation
    </ResponseField>

    <ResponseField name="nativeEvent" type="Event">
      The original browser event that triggered the drag
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="dragmove" type="Event">
  Fires during movement. Can be prevented.

  <Expandable title="Properties">
    <ResponseField name="operation" type="object">
      The current drag operation
    </ResponseField>

    <ResponseField name="to" type="Point">
      The destination coordinates
    </ResponseField>

    <ResponseField name="by" type="Point">
      The movement delta
    </ResponseField>

    <ResponseField name="nativeEvent" type="Event">
      The original browser event
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="dragover" type="Event">
  Fires when over a droppable. Call `event.preventDefault()` to prevent the default behavior of plugins that respond to this event.

  <Expandable title="Properties">
    <ResponseField name="operation" type="object">
      The current drag operation
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="collision" type="Event">
  Fires on droppable collision. Can be prevented.

  <Expandable title="Properties">
    <ResponseField name="collisions" type="Collision[]">
      Array of detected collisions with droppable targets
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="dragend" type="Event">
  Fires when drag ends.

  <Expandable title="Properties">
    <ResponseField name="operation" type="object">
      The completed drag operation
    </ResponseField>

    <ResponseField name="canceled" type="boolean">
      Whether the operation was canceled
    </ResponseField>

    <ResponseField name="nativeEvent" type="Event">
      The original browser event
    </ResponseField>
  </Expandable>
</ResponseField>

## Registration

The manager's `registry` tracks draggable and droppable elements:

```js theme={null}
// Manual registration
const cleanup = manager.registry.register(draggable);
cleanup(); // Or manager.registry.unregister(draggable);

// Auto-registration with manager reference
const draggable = new Draggable({
  id: 'draggable-1',
  element,
}, manager);

// Opt out of auto-registration
const draggable = new Draggable({
  id: 'draggable-1',
  element,
  register: false
}, manager);
```

<Tip>
  Elements automatically register when created with a manager reference. Only use manual registration for advanced use cases.
</Tip>

## API Reference

### Properties

* `registry`: Tracks active elements and extensions
  * `draggables`: Map of registered draggable elements
  * `droppables`: Map of registered droppable elements
  * `plugins`: Registry of active plugins
  * `sensors`: Registry of active sensors
  * `modifiers`: Registry of active modifiers

* `dragOperation`: Current drag operation state
  * `source`: Currently dragged element
  * `target`: Current drop target
  * `position`: Current drag coordinates
  * `status`: Current operation status
  * `canceled`: Whether operation was canceled

* `monitor`: Event system
  * `addEventListener`: Add event listener
  * `removeEventListener`: Remove listener

* `renderer`: Integration with asynchronous renderers such as React

### Methods

<ParamField path="destroy()" type="function">
  Clean up the manager and all registered elements:

  * Unregisters all draggables and droppables
  * Cleans up all plugins, sensors, and modifiers
  * Removes all event listeners
</ParamField>

## Lifecycle

1. **Initialization**
   * Manager created
   * Default plugins and sensors registered
   * Custom configuration applied

2. **Registration**
   * Draggable and droppable elements register
   * Plugins initialize
   * Event listeners bound

3. **Operation**
   * Drag operations tracked
   * Events dispatched
   * Collisions detected

4. **Cleanup**
   * Elements unregister
   * Event listeners removed
   * Resources released
