apps/docs/react/hooks/use-draggable.mdx
import {Story} from '/snippets/story.mdx'; import {CodeSandbox} from '/snippets/sandbox.mdx'; import {draggableStyles} from '/snippets/code.mdx';
<CodeSandbox files={{ 'App.js': {code: app, hidden: true}, 'Draggable.js': {code, active: true}, 'styles.css': {code: draggableStyles, hidden: true}, }} height={220} previewHeight={200} hero />
The useDraggable hook requires an id and accepts all the same options as the Draggable class. Refer to the Input section below for more information.
The useDraggable hook accepts the following arguments:
The useDraggable hook returns an object containing the following properties:
To specify a drag handle, provide a reference to an element and pass it as the handle argument to the useDraggable hook. Alternatively, you can consume the handleRef ref callback to connect the drag handle element.
import {useDraggable} from '@dnd-kit/react';
function Draggable(props) {
const {ref, handleRef} = useDraggable({
id: props.id,
});
return (
<div ref={ref}>
Draggable
<button ref={handleRef}>Drag handle</button>
</div>
);
}
Use modifiers to modify or restrict the behavior of draggable elements.
Modifiers let you dynamically modify the movement coordinates that are detected by sensors. They can be used for a wide range of use cases, for example:
Modifiers can be applied globally on the <DragDropProvider> component or locally on individual draggable elements.
Here is an example of how to restrict dragging to the horizontal axis:
import {useDraggable} from '@dnd-kit/react';
import {RestrictToHorizontalAxis} from '@dnd-kit/abstract/modifiers';
function Draggable({id}) {
const {ref} = useDraggable({
id,
modifiers: [RestrictToHorizontalAxis],
});
}
And here is an example of how to restrict dragging to the container element of the draggable:
import {useDraggable} from '@dnd-kit/react';
import {RestrictToElement} from '@dnd-kit/dom/modifiers';
function Draggable({id}) {
const {ref} = useDraggable({
id,
modifiers: [RestrictToElement.configure({element: document.body})],
});
}
export const app = ` import {Draggable} from './Draggable.js'; import './styles.css';
export default function App() { return <Draggable id="draggable"/>; } `.trim();
export const code = ` import {useDraggable} from '@dnd-kit/react';
export function Draggable(props) { const {ref} = useDraggable({ id: props.id, });
return <button ref={ref} className="btn">draggable</button>; } `.trim();
You can render a completely different element while the draggable element is being dragged by using the <DragOverlay> component.
import {useDraggable, DragOverlay} from '@dnd-kit/react';
function Draggable() {
const {ref} = useDraggable({
id: 'draggable',
});
return (
<>
<button ref={ref}>
Draggable
</button>
<DragOverlay>
<div>I will be rendered while dragging...</div>
</DragOverlay>
</>
);
}
The <DragOverlay> component will only render its children when a drag operation is in progress. This can be useful for rendering a completely different element while the draggable element is being dragged.
To get around the fact that the <DragOverlay> component should only rendered once, you can also pass a function as a child to the <DragOverlay> component, which will receive the source as an argument. This can be useful for rendering a clone of the source element while it is being dragged.
import {useDraggable, DragOverlay} from '@dnd-kit/react';
function App(props) {
return (
<DragDropProvider>
<Draggable id="foo" />
<Draggable id="bar" />
<DragOverlay>
{source => (
<div>
Dragging {source.id}
</div>
)}
</DragOverlay>
</DragDropProvider>
);
}