A simple component for making elements draggable.
$ 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.
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.
The <Draggable/>
component transparently adds draggable to whatever element is supplied as this.props.children
.
Note: Only a single element is allowed or an Error will be thrown.
Props:
{
// Called when dragging starts. If `false` is returned from this method,
// dragging will cancel.
// These callbacks are called with the arity
// (event: Event,
// {
// position: {left: number, top: number},
// deltaX: number,
// deltaY: number
// }
// )
onStart: Function,
// Called while dragging.
onDrag: Function,
// Called when dragging stops.
onStop: Function,
// Called whenever the user mouses down. Called regardless of handle or
// disabled status.
onMouseDown: Function,
// Specifies the `x` and `y` that the dragged item should start at.
// This is generally not necessary to use (you can use absolute or relative
// positioning of the child directly), but can be helpful for uniformity in
// your callbacks and with css transforms.
start: {x: number, y: number},
// If true, will not call any drag handlers.
disabled: boolean,
// Specifies a selector to be used to prevent drag initialization.
// Example: '.body'
cancel: string,
// Specifies a selector to be used as the handle that initiates drag.
// Example: '.handle'
handle: string,
// Determines which axis the draggable can move. Accepted values:
// - `both` allows movement horizontally and vertically (default).
// - `x` limits movement to horizontal axis.
// - `y` limits movement to vertical axis.
axis: string,
// Specifies movement boundaries. Accepted values:
// - `parent` restricts movement within the node's offsetParent
// (nearest node with position relative or absolute), or
// - An object with `left, top, right, and bottom` properties.
// These indicate how far in each direction the draggable
// can be moved.
bounds: {left: number, top: number, right: number, bottom: number} | string,
// Specifies the x and y that dragging should snap to.
grid: [number, number],
// Specifies the zIndex to use while dragging.
zIndex: number
}
Note that sending className
, style
, or transform
as properties will error - set them on the child element
directly.
/** @jsx React.DOM */
var React = require('react'),
Draggable = require('react-draggable');
var App = React.createClass({
handleStart: function (event, ui) {
console.log('Event: ', event);
console.log('Position: ', ui.position);
},
handleDrag: function (event, ui) {
console.log('Event: ', event);
console.log('Position: ', ui.position);
},
handleStop: function (event, ui) {
console.log('Event: ', event);
console.log('Position: ', ui.position);
},
render: function () {
return (
<Draggable
axis="x"
handle=".handle"
start={{x: 0, y: 0}}
moveOnStartChange={false}
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>
);
}
});
React.renderComponent(<App/>, document.body);
For users that require more control, a <DraggableCore>
element is available. This is useful for more programmatic
usage of the element. See React-Resizable and
React-Grid-Layout for some examples of this.
<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.
<DraggableCore>
takes all of the above <Draggable>
options, with the exception of:
axis
bounds
grid
start
zIndex
Drag callbacks are called with the following parameters:
{
node: Node
position:
{
// lastX + deltaX === clientX
deltaX: number, deltaY: number,
lastX: number, lastY: number,
clientX: number, clientY: number
}
};
- 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
- Update CHANGELOG
make release-patch
,make release-minor
, ormake-release-major
make publish
MIT