apps/docs/concepts/draggable.mdx
import {Story} from '/snippets/story.mdx'; import {CodeSandbox} from '/snippets/sandbox.mdx'; import {draggableStyles} from '/snippets/code.mdx';
First, create a DragDropManager instance to orchestrate the drag and drop system. Then use the Draggable class to make elements draggable:
export const code = ` import {Draggable, DragDropManager} from '@dnd-kit/dom';
export function App() { const manager = new DragDropManager();
const element = document.createElement('button'); element.innerText = 'draggable'; element.classList.add('btn');
const draggable = new Draggable({ id: 'draggable-1', // Required - must be unique element, }, manager);
document.body.appendChild(element); } `.trim();
<CodeSandbox files={{
'index.js': {code: import './styles.css';\nimport {App} from './draggable.js';\n\nApp();, hidden: true},
'draggable.js': {code, active: true},
'styles.css': {code: draggableStyles, hidden: true},
}} height={360} previewHeight={200} template="vanilla" hero />
By default, the entire element can be used to initiate dragging. You can restrict dragging to a specific handle element:
const element = document.createElement('div');
const handle = document.createElement('div');
handle.classList.add('handle');
handle.innerHTML = '⋮'; // Three dots menu icon for drag handle
element.appendChild(handle);
const draggable = new Draggable({
id: 'draggable-1',
element,
handle, // Only allow dragging from the handle
}, manager);
You can assign types to draggable elements to restrict which droppable targets they can be dropped on:
// Assign a type
const draggable = new Draggable({
id: 'draggable-1',
element,
type: 'item', // Only droppables accepting 'item' type will be valid targets
}, manager);
You can customize how the element behaves while being dragged using the Feedback plugin's per-entity configuration:
import {Draggable, DragDropManager, Feedback} from '@dnd-kit/dom';
const draggable = new Draggable({
id: 'draggable-1',
element,
plugins: [Feedback.configure({ feedback: 'clone' })],
}, manager);
Available feedback options:
'default': The original element moves with the drag (best for most cases)'clone': A copy of the element stays in place while the original moves (good for drag-to-copy)'move': The element moves without a placeholder (minimal visual feedback)'none': No visual feedback (useful for custom drag overlays)The Draggable class accepts the following arguments:
The Draggable instance provides these key properties:
id: The unique identifierelement: The main DOM elementhandle: The drag handle element (if specified)type: The assigned typedisabled: Whether dragging is disabledisDragging: Whether this element is currently being draggedisDropping: Whether this element is being droppedregister(): Register this draggable with the managerunregister(): Remove this draggable from the managerdestroy(): Clean up this draggable instance and remove all listeners