react-draggable-io v1.0.0
React-Draggable-IO is a fork off React-Draggable that uses React v0.14 Beta. This is NOT meant to be a replacement for React-Draggable and this is NOT production battle tested (maybe?) so use it at your own risk. React-Draggable-IO exists for people to use React-Draggable with the latest beta version of React so they don't have to depend on the framework to use the latest and greatest.
react-draggable
A simple component for making elements draggable.
Demo
Installing
$ npm install react-draggable-io
If you aren't using browserify/webpack, a UMD version of react-draggable is available.
Details
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.
API
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.
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
is used along with onMouseUp to keep track of dragging state.onMouseUp
is used along with onMouseDown to keep track of dragging state.onTouchStart
is used along with onTouchEnd to keep track of dragging state.onTouchEnd
is used along with onTouchStart to keep track of dragging state.
React.DOM elements support the above six 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 might find this React page helpful.
Props:
axis
: 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.
handle
: specifies a selector to be used as the handle that initiates drag.
cancel
: specifies a selector to be used to prevent drag initialization.
grid
: specifies the x and y that dragging should snap to.
bounds
: 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. See example/index.html for more on this.
start
: 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.
moveOnStartChange
: if true (it defaults false), will move the element if there is a change in start
. We set this by default to false
because it can cause unwanted effects if you are not aware of it.
zIndex
: specifies the zIndex to use while dragging.
onStart
: called when dragging starts.
onDrag
: called while dragging.
onStop
: called when dragging stops.
Example usage
/** @jsx React.DOM */
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Draggable from 'react-draggable-io';
class App extends Component {
/**
* use this form of function definition on event handlers,
* so that that they have access to `this`
* https://babeljs.io/blog/2015/06/07/react-on-es6-plus/
* @param {Event} event the event to handle
* @param {Draggable} ui the `Draggable` element
*/
handleStart = (event, ui) => {
console.log('Event: ', event);
console.log('Position: ', ui.position);
}
/**
* use this form of function definition on event handlers,
* so that that they have access to `this`
* https://babeljs.io/blog/2015/06/07/react-on-es6-plus/
* @param {Event} event the event to handle
* @param {Draggable} ui the `Draggable` element
*/
handleDrag = (event, ui) => {
console.log('Event: ', event);
console.log('Position: ', ui.position);
}
/**
* use this form of function definition on event handlers,
* so that that they have access to `this`
* https://babeljs.io/blog/2015/06/07/react-on-es6-plus/
* @param {Event} event the event to handle
* @param {Draggable} ui the `Draggable` element
*/
handleStop = (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>
);
}
}
window.onload = () => {
ReactDOM.render(<App/>, document.getElementById('app'));
};
State Problems?
<Draggable>
is a stateful component. This means that it is storing its current drag offsets in its internal state.
This can cause problems with certain integrations. For example, if you change the position of the element manually,
<Draggable>
can get into trouble as it assumes a translation in the DOM. If you see an element jump around the page
when you click it, this is affecting you.
This is an unfortunate side-effect of dragging, which is inherently stateful.
If you move the element manually, you have two options:
- Feed the
<Draggable>
anx
andy
parameter in thestart
param, and change it as you go while settingmoveOnStartChange
totrue
, or, - When moving the
<Draggable>
, ref the element and callresetState()
.
Dragging images
The HTML5 Drag & Drop API can interact strangely with <Draggable>
, especially on <img>
tags.
If you want an <img>
to be draggable, set <img draggable="false" />
. See the
corresponding issue.
License
MIT
9 years ago