Skip to main content

Overview

The DragDropManager is the core class that orchestrates all drag-and-drop operations. It manages the lifecycle of drag operations, coordinates sensors and plugins, and maintains a registry of draggable and droppable elements.

Constructor

const manager = new DragDropManager(input?);

Parameters

input
Input
Configuration options for the manager

Default Preset

The manager automatically includes a default preset of sensors and plugins:
const defaultPreset = {
  sensors: [PointerSensor, KeyboardSensor],
  plugins: [
    Accessibility,
    AutoScroller,
    Cursor,
    Feedback,
    PreventSelection
  ],
  modifiers: []
};
Additional plugins are always included:
  • ScrollListener - Tracks scroll events
  • Scroller - Manages scrolling logic
  • StyleInjector - Injects plugin styles

Usage

Basic Setup

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

const manager = new DragDropManager();

Custom Configuration

import {
  DragDropManager,
  PointerSensor,
  Accessibility,
  Feedback
} from '@dnd-kit/dom';

const manager = new DragDropManager({
  sensors: [
    // Configure sensors with options
    PointerSensor.configure({
      activationConstraints: {
        delay: 100,
        tolerance: 5
      }
    })
  ],
  plugins: [
    Accessibility,
    // Configure feedback plugin
    Feedback.configure({
      dropAnimation: {
        duration: 200,
        easing: 'ease-out'
      }
    })
  ]
});

Disable Default Preset

// Disable all defaults
const manager = new DragDropManager({
  sensors: null,
  plugins: null
});

// Or selectively override
const manager = new DragDropManager({
  sensors: [PointerSensor], // Only pointer, no keyboard
  plugins: [Feedback] // Only feedback, no other plugins
});

Properties

dragOperation

manager.dragOperation.status; // { idle: boolean, initializing: boolean, ... }
manager.dragOperation.source; // Current draggable being dragged
manager.dragOperation.target; // Current droppable target
manager.dragOperation.position; // Current drag position
manager.dragOperation.transform; // Current transform { x, y }
Access the current drag operation state.

registry

manager.registry.draggables; // Collection of registered draggables
manager.registry.droppables; // Collection of registered droppables
manager.registry.plugins; // Collection of active plugins
manager.registry.sensors; // Collection of active sensors
Access registered entities, plugins, and sensors.

monitor

manager.monitor.addEventListener('dragstart', handler);
manager.monitor.addEventListener('dragover', handler);
manager.monitor.addEventListener('dragend', handler);
Event monitor for drag lifecycle events.

actions

Internal actions used by sensors:
// Typically used by sensor implementations
manager.actions.start({ event, source, coordinates });
manager.actions.move({ event, to, by });
manager.actions.stop({ event, canceled });

Events

Listen to drag-and-drop events using the monitor:

dragstart

manager.monitor.addEventListener('dragstart', (event) => {
  console.log('Started dragging:', event.source.id);
});
event
DragStartEvent

dragmove

manager.monitor.addEventListener('dragmove', (event) => {
  console.log('Position:', event.position);
});
event
DragMoveEvent

dragover

manager.monitor.addEventListener('dragover', (event) => {
  console.log('Over:', event.target?.id);
});
event
DragOverEvent

dragend

manager.monitor.addEventListener('dragend', (event) => {
  if (event.target) {
    console.log('Dropped on:', event.target.id);
  } else if (event.canceled) {
    console.log('Drag canceled');
  }
});
event
DragEndEvent

collision

manager.monitor.addEventListener('collision', (event) => {
  console.log('Collision:', event.collision);
});
Fired when collision detection runs.

beforedragstart

manager.monitor.addEventListener('beforedragstart', (event) => {
  // Called before drag initialization
});
Fired before the drag operation is fully initialized.

Example: Complete Setup

import {
  DragDropManager,
  Draggable,
  Droppable,
  PointerSensor,
  KeyboardSensor,
  Accessibility,
  Feedback
} from '@dnd-kit/dom';

// Create manager with custom configuration
const manager = new DragDropManager({
  sensors: [
    PointerSensor.configure({
      activationConstraints(event) {
        // Custom activation logic
        return event.pointerType === 'touch'
          ? [new PointerActivationConstraints.Delay({ value: 250, tolerance: 5 })]
          : undefined;
      }
    }),
    KeyboardSensor
  ],
  plugins: [
    Accessibility.configure({
      announcements: {
        dragstart: (event) => `Picked up ${event.source.id}`,
        dragend: (event) => event.target
          ? `Dropped on ${event.target.id}`
          : 'Drag cancelled'
      }
    }),
    Feedback.configure({
      dropAnimation: { duration: 200 }
    })
  ]
});

// Register draggables and droppables
const draggable = new Draggable(
  { id: 'item-1', element: document.getElementById('item-1') },
  manager
);

const droppable = new Droppable(
  { id: 'zone-1', element: document.getElementById('zone-1') },
  manager
);

// Listen to events
manager.monitor.addEventListener('dragend', (event) => {
  if (event.target) {
    console.log(`${event.source.id} dropped on ${event.target.id}`);
  }
});

Type Definitions

interface Input extends DragDropManagerInput<DragDropManager> {
  plugins?: Plugins | null;
  sensors?: Sensors | null;
  modifiers?: Modifiers | null;
}

class DragDropManager<
  T extends Data = Data,
  U extends Draggable<T> = Draggable<T>,
  V extends Droppable<T> = Droppable<T>
> extends AbstractDragDropManager<U, V> {
  constructor(input?: Input);
}

Build docs developers (and LLMs) love