What is react-draggable?
The react-draggable npm package allows React components to be draggable within the DOM. It provides a simple way to make elements draggable and offers various customization options such as grid snapping, axis locking, and event handling for drag actions.
What are react-draggable's main functionalities?
Basic Dragging
This code snippet enables basic dragging functionality for the enclosed <div> element.
{"<Draggable><div>I can be dragged</div></Draggable>"}
Controlled Draggable
This example shows a controlled component where the position is managed by the component's state, allowing for more complex interactions.
{"<Draggable position={this.state.position} onDrag={this.handleDrag}><div>I can be dragged</div></Draggable>"}
Axis Constraints
This code restricts the dragging movement to the horizontal axis.
{"<Draggable axis='x'><div>I can only be dragged horizontally</div></Draggable>"}
Grid Snapping
This snippet makes the element snap to a grid pattern as it's being dragged.
{"<Draggable grid={[25, 25]}><div>I snap to a 25x25 grid</div></Draggable>"}
Bounds Limitation
This code ensures that the draggable element cannot be moved outside the bounds of its parent container.
{"<Draggable bounds='parent'><div>I can't be dragged outside my parent</div></Draggable>"}
Other packages similar to react-draggable
react-beautiful-dnd
This package provides a higher level of abstraction for creating draggable and droppable interfaces, focusing on vertical and horizontal lists. It's more suitable for complex drag-and-drop interfaces, compared to react-draggable which is more low-level.
react-dnd
React DnD is a set of React utilities to help you build complex drag and drop interfaces while keeping your components decoupled. It is more comprehensive than react-draggable and uses the HTML5 drag and drop API.
react-sortable-hoc
This package provides components and higher-order components to make elements sortable via drag-and-drop. It's specifically designed for creating sortable lists and grids, unlike react-draggable which is for general-purpose dragging.
react-grid-layout
React Grid Layout is a grid layout system much like Packery or Gridster, for React. It allows users to create draggable and resizable layouts. It's more specialized for layout management compared to react-draggable which is for dragging elements.
React-Draggable

A simple component for making elements draggable.
<Draggable>
<div>I can now be moved around!</div>
</Draggable>
Technical Documentation
Installing
$ npm install react-draggable
If you aren't using browserify/webpack, a
UMD version of react-draggable is available. It is updated per-release only.
This bundle is also what is loaded when installing from npm. It expects external React
and ReactDOM
.
If you want a UMD version of the latest master
revision, you can generate it yourself from master by cloning this
repository and running $ make
. This will create umd dist files in the dist/
folder.
Exports
The default export is <Draggable>
. At the .DraggableCore
property is <DraggableCore>
.
Here's how to use it:
import Draggable from 'react-draggable';
import {DraggableCore} from 'react-draggable';
import Draggable, {DraggableCore} from 'react-draggable';
let Draggable = require('react-draggable');
let DraggableCore = Draggable.DraggableCore;
<Draggable>
A <Draggable>
element wraps an existing element and extends it with new event handlers and styles.
It does not create a wrapper element in the DOM.
Draggable items are moved using CSS Transforms. This allows items to be dragged regardless of their current
positioning (relative, absolute, or static). Elements can also be moved between drags without incident.
If the item you are dragging already has a CSS Transform applied, it will be overwritten by <Draggable>
. Use
an intermediate wrapper (<Draggable><span>...</span></Draggable>
) in this case.
Draggable Usage
View the Demo and its
source for more.
import React from 'react');
import ReactDOM from 'react-dom';
import Draggable from 'react-draggable';
class App extends React.Element {
eventLogger = (e: MouseEvent, data: Object) => {
console.log('Event: ', event);
console.log('Data: ', data);
};
render() {
return (
<Draggable
axis="x"
handle=".handle"
defaultPosition={{x: 0, y: 0}}
position={null}
grid={[25, 25]}
zIndex={100}
onStart={this.handleStart}
onDrag={this.handleDrag}
onStop={this.handleStop}>
<div>
<div className="handle">Drag from here</div>
<div>This readme is really dragging on...</div>
</div>
</Draggable>
);
}
}
ReactDOM.render(<App/>, document.body);
Draggable API
The <Draggable/>
component transparently adds draggability to its children.
Note: Only a single child is allowed or an Error will be thrown.
For the <Draggable/>
component to correctly attach itself to its child, the child element must provide support
for the following props:
style
is used to give the transform css to the child.
className
is used to apply the proper classes to the object being dragged.
onMouseDown
, onMouseUp
, onTouchStart
, and onTouchEnd
are used to keep track of dragging state.
React.DOM elements support the above properties by default, so you may use those elements as children without
any changes. If you wish to use a React component you created, you'll need to be sure to
transfer prop.
<Draggable>
Props:
type DraggableEventHandler = (e: Event, data: DraggableData) => void | false;
type DraggableData = {
node: HTMLElement,
x: number, y: number,
deltaX: number, deltaY: number,
lastX: number, lastY: number
};
{
allowAnyClick: boolean,
axis: string,
bounds: {left: number, top: number, right: number, bottom: number} | string,
cancel: string,
defaultPosition: {x: number, y: number},
disabled: boolean,
grid: [number, number],
handle: string,
onMouseDown: (e: MouseEvent) => void,
onStart: DraggableEventHandler,
onDrag: DraggableEventHandler,
onStop: DraggableEventHandler,
position: {x: number, y: number}
}
Note that sending className
, style
, or transform
as properties will error - set them on the child element
directly.
Controlled vs. Uncontrolled
<Draggable>
is a 'batteries-included' component that manages its own state. If you want to completely
control the lifecycle of the component, use <DraggableCore>
.
For some users, they may want the nice state management that <Draggable>
provides, but occasionally want
to programmatically reposition their components. <Draggable>
allows this customization via a system that
is similar to how React handles form components.
If the prop position: {x: number, y: number}
is defined, the <Draggable>
will ignore its internal state and use
the provided position instead. Altneratively, you can seed the position using defaultPosition
. Technically, since
<Draggable>
works only on position deltas, you could also seed the initial position using CSS top/left
.
We make one modification to the React philosophy here - we still allow dragging while a component is controlled.
We then expect you to use at least an onDrag
or onStop
handler to synchronize state.
To disable dragging while controlled, send the prop disabled={true}
- at this point the <Draggable>
will operate
like a completely static component.
<DraggableCore>
For users that require absolute control, a <DraggableCore>
element is available. This is useful as an abstraction
over touch and mouse events, but with full control. <DraggableCore>
has no internal state.
See React-Resizable and
React-Grid-Layout for some usage examples.
<DraggableCore>
is a useful building block for other libraries that simply want to abstract browser-specific
quirks and receive callbacks when a user attempts to move an element. It does not set styles or transforms
on itself and thus must have callbacks attached to be useful.
DraggableCore API
<DraggableCore>
takes a limited subset of options:
{
allowAnyClick: boolean,
cancel: string,
disabled: boolean,
enableUserSelectHack: boolean,
grid: [number, number],
handle: string,
onStart: DraggableEventHandler,
onDrag: DraggableEventHandler,
onStop: DraggableEventHandler
onMouseDown: (e: MouseEvent) => void
}
Note that there is no start position. <DraggableCore>
simply calls drag
handlers with the below parameters,
indicating its position (as inferred from the underlying MouseEvent) and deltas. It is up to the parent
to set actual positions on <DraggableCore>
.
Drag callbacks (onStart
, onDrag
, onStop
) are called with the same arguments as <Draggable>
.
Contributing
- Fork the project
- Run the project in development mode:
$ npm run dev
- Make changes.
- Add appropriate tests
$ npm test
- If tests don't pass, make them pass.
- Update README with appropriate docs.
- Commit and PR
Release checklist
- Update CHANGELOG
make release-patch
, make release-minor
, or make-release-major
make publish
License
MIT
2.0.0-beta3 (Apr 19, 2016)
- Flow comments are now in the build. Other projects, such as React-Grid-Layout and React-Resizable, will
rely on them in their build and export their own comments.