react-draggable
Advanced tools
Comparing version 0.4.2 to 0.5.0
@@ -45,1 +45,5 @@ # Changelog | ||
- Remove unnecessary `emptyFunction` and `React.addons.classSet` imports. | ||
### 0.4.3 (Apr 30, 2015) | ||
- Fix React.addons error caused by faulty test. |
'use strict'; | ||
/** @jsx React.DOM */ | ||
var React = require('react'); | ||
var emptyFunction = function(){}; | ||
var assign = require('object-assign'); | ||
var classNames = require('classnames'); | ||
// | ||
// Helpers. See Element definition below this section. | ||
// | ||
function createUIEvent(draggable) { | ||
return { | ||
position: { | ||
top: draggable.state.clientY, | ||
left: draggable.state.clientX | ||
} | ||
}; | ||
// State changes are often (but not always!) async. We want the latest value. | ||
var state = draggable._pendingState || draggable.state; | ||
return { | ||
node: draggable.getDOMNode(), | ||
position: { | ||
top: state.clientY, | ||
left: state.clientX | ||
} | ||
}; | ||
} | ||
function canDragY(draggable) { | ||
return draggable.props.axis === 'both' || | ||
draggable.props.axis === 'y'; | ||
return draggable.props.axis === 'both' || | ||
draggable.props.axis === 'y'; | ||
} | ||
function canDragX(draggable) { | ||
return draggable.props.axis === 'both' || | ||
draggable.props.axis === 'x'; | ||
return draggable.props.axis === 'both' || | ||
draggable.props.axis === 'x'; | ||
} | ||
function isFunction(func) { | ||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]' | ||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]'; | ||
} | ||
@@ -32,4 +40,4 @@ | ||
function findInArray(array, callback) { | ||
for (var i = 0, length = array.length, element = null; i < length, element = array[i]; i++) { | ||
if (callback.apply(callback, [element, i, array])) return element; | ||
for (var i = 0, length = array.length; i < length; i++) { | ||
if (callback.apply(callback, [array[i], i, array])) return array[i]; | ||
} | ||
@@ -59,4 +67,4 @@ } | ||
// Do Browser Stuff | ||
var isTouchDevice = 'ontouchstart' in window // works on most browsers | ||
|| 'onmsgesturechange' in window; // works on ie10 on ms surface | ||
var isTouchDevice = 'ontouchstart' in window || // works on most browsers | ||
'onmsgesturechange' in window; // works on ie10 on ms surface | ||
@@ -97,251 +105,274 @@ } | ||
clientY: position.clientY | ||
} | ||
}; | ||
} | ||
function addEvent(el, event, handler) { | ||
if (!el) { return; } | ||
if (el.attachEvent) { | ||
el.attachEvent('on' + event, handler); | ||
} else if (el.addEventListener) { | ||
el.addEventListener(event, handler, true); | ||
} else { | ||
el['on' + event] = handler; | ||
} | ||
if (!el) { return; } | ||
if (el.attachEvent) { | ||
el.attachEvent('on' + event, handler); | ||
} else if (el.addEventListener) { | ||
el.addEventListener(event, handler, true); | ||
} else { | ||
el['on' + event] = handler; | ||
} | ||
} | ||
function removeEvent(el, event, handler) { | ||
if (!el) { return; } | ||
if (el.detachEvent) { | ||
el.detachEvent('on' + event, handler); | ||
} else if (el.removeEventListener) { | ||
el.removeEventListener(event, handler, true); | ||
} else { | ||
el['on' + event] = null; | ||
} | ||
if (!el) { return; } | ||
if (el.detachEvent) { | ||
el.detachEvent('on' + event, handler); | ||
} else if (el.removeEventListener) { | ||
el.removeEventListener(event, handler, true); | ||
} else { | ||
el['on' + event] = null; | ||
} | ||
} | ||
module.exports = React.createClass({ | ||
displayName: 'Draggable', | ||
function snapToGrid(draggable, clientX, clientY) { | ||
var stateX = parseInt(draggable.state.clientX, 10); | ||
var stateY = parseInt(draggable.state.clientY, 10); | ||
var directionX = clientX < stateX ? -1 : 1; | ||
var directionY = clientY < stateY ? -1 : 1; | ||
propTypes: { | ||
/** | ||
* `axis` determines which axis the draggable can move. | ||
* | ||
* 'both' allows movement horizontally and vertically. | ||
* 'x' limits movement to horizontal axis. | ||
* 'y' limits movement to vertical axis. | ||
* | ||
* Defaults to 'both'. | ||
*/ | ||
axis: React.PropTypes.oneOf(['both', 'x', 'y']), | ||
clientX = Math.abs(clientX - stateX) >= draggable.props.grid[0] ? | ||
(stateX + (draggable.props.grid[0] * directionX)) : | ||
stateX; | ||
/** | ||
* `handle` specifies a selector to be used as the handle that initiates drag. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable handle=".handle"> | ||
* <div> | ||
* <div className="handle">Click me to drag</div> | ||
* <div>This is some other content</div> | ||
* </div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
handle: React.PropTypes.string, | ||
clientY = Math.abs(clientY - stateY) >= draggable.props.grid[1] ? | ||
(stateY + (draggable.props.grid[1] * directionY)) : | ||
stateY; | ||
/** | ||
* `cancel` specifies a selector to be used to prevent drag initialization. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return( | ||
* <Draggable cancel=".cancel"> | ||
* <div> | ||
* <div className="cancel">You can't drag from here</div> | ||
* <div>Dragging here works fine</div> | ||
* </div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
cancel: React.PropTypes.string, | ||
return [clientX, clientY]; | ||
} | ||
/** | ||
* `grid` specifies the x and y that dragging should snap to. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable grid={[25, 25]}> | ||
* <div>I snap to a 25 x 25 grid</div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
grid: React.PropTypes.arrayOf(React.PropTypes.number), | ||
// Useful for preventing blue highlights all over everything when dragging. | ||
var userSelectStyle = { | ||
WebkitUserSelect: 'none', | ||
MozUserSelect: 'none', | ||
msUserSelect: 'none', | ||
OUserSelect: 'none', | ||
userSelect: 'none', | ||
}; | ||
/** | ||
* `start` specifies the x and y that the dragged item should start at | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable start={{x: 25, y: 25}}> | ||
* <div>I start with left: 25px; top: 25px;</div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
start: React.PropTypes.object, | ||
function createCSSTransform(style) { | ||
if (!style.x && !style.y) return {}; | ||
// Replace unitless items with px | ||
var x = style.x + 'px'; | ||
var y = style.y + 'px'; | ||
return { | ||
transform: 'translate(' + x + ',' + y + ')', | ||
WebkitTransform: 'translate(' + x + ',' + y + ')', | ||
OTransform: 'translate(' + x + ',' + y + ')', | ||
msTransform: 'translate(' + x + ',' + y + ')', | ||
MozTransform: 'translate(' + x + ',' + y + ')' | ||
}; | ||
} | ||
/** | ||
* `zIndex` specifies the zIndex to use while dragging. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable zIndex={100}> | ||
* <div>I have a zIndex</div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
zIndex: React.PropTypes.number, | ||
/** | ||
* Called when dragging starts. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onStart: React.PropTypes.func, | ||
// | ||
// End Helpers. | ||
// | ||
/** | ||
* Called while dragging. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onDrag: React.PropTypes.func, | ||
// | ||
// Define <Draggable> | ||
// | ||
/** | ||
* Called when dragging stops. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onStop: React.PropTypes.func, | ||
module.exports = React.createClass({ | ||
displayName: 'Draggable', | ||
/** | ||
* A workaround option which can be passed if onMouseDown needs to be accessed, since it'll always be blocked (due to that there's internal use of onMouseDown) | ||
* | ||
*/ | ||
onMouseDown: React.PropTypes.func | ||
}, | ||
propTypes: { | ||
/** | ||
* `axis` determines which axis the draggable can move. | ||
* | ||
* 'both' allows movement horizontally and vertically. | ||
* 'x' limits movement to horizontal axis. | ||
* 'y' limits movement to vertical axis. | ||
* | ||
* Defaults to 'both'. | ||
*/ | ||
axis: React.PropTypes.oneOf(['both', 'x', 'y']), | ||
componentWillUnmount: function() { | ||
// Remove any leftover event handlers | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
/** | ||
* `handle` specifies a selector to be used as the handle that initiates drag. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable handle=".handle"> | ||
* <div> | ||
* <div className="handle">Click me to drag</div> | ||
* <div>This is some other content</div> | ||
* </div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
handle: React.PropTypes.string, | ||
getDefaultProps: function () { | ||
return { | ||
axis: 'both', | ||
handle: null, | ||
cancel: null, | ||
grid: null, | ||
start: { | ||
x: 0, | ||
y: 0 | ||
}, | ||
zIndex: NaN, | ||
onStart: emptyFunction, | ||
onDrag: emptyFunction, | ||
onStop: emptyFunction, | ||
onMouseDown: emptyFunction | ||
}; | ||
}, | ||
/** | ||
* `cancel` specifies a selector to be used to prevent drag initialization. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return( | ||
* <Draggable cancel=".cancel"> | ||
* <div> | ||
* <div className="cancel">You can't drag from here</div> | ||
* <div>Dragging here works fine</div> | ||
* </div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
cancel: React.PropTypes.string, | ||
getInitialState: function () { | ||
return { | ||
// Whether or not currently dragging | ||
dragging: false, | ||
/** | ||
* `grid` specifies the x and y that dragging should snap to. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable grid={[25, 25]}> | ||
* <div>I snap to a 25 x 25 grid</div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
grid: React.PropTypes.arrayOf(React.PropTypes.number), | ||
// Start top/left of this.getDOMNode() | ||
startX: 0, startY: 0, | ||
/** | ||
* `zIndex` specifies the zIndex to use while dragging. | ||
* | ||
* Example: | ||
* | ||
* ```jsx | ||
* var App = React.createClass({ | ||
* render: function () { | ||
* return ( | ||
* <Draggable zIndex={100}> | ||
* <div>I have a zIndex</div> | ||
* </Draggable> | ||
* ); | ||
* } | ||
* }); | ||
* ``` | ||
*/ | ||
zIndex: React.PropTypes.number, | ||
// Offset between start top/left and mouse top/left | ||
offsetX: 0, offsetY: 0, | ||
/** | ||
* Called when dragging starts. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onStart: React.PropTypes.func, | ||
// Current top/left of this.getDOMNode() | ||
clientX: this.props.start.x, clientY: this.props.start.y | ||
}; | ||
}, | ||
/** | ||
* Called while dragging. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onDrag: React.PropTypes.func, | ||
handleDragStart: function (e) { | ||
/** | ||
* Called when dragging stops. | ||
* | ||
* Example: | ||
* | ||
* ```js | ||
* function (event, ui) {} | ||
* ``` | ||
* | ||
* `event` is the Event that was triggered. | ||
* `ui` is an object: | ||
* | ||
* ```js | ||
* { | ||
* position: {top: 0, left: 0} | ||
* } | ||
* ``` | ||
*/ | ||
onStop: React.PropTypes.func, | ||
/** | ||
* A workaround option which can be passed if onMouseDown needs to be accessed, | ||
* since it'll always be blocked (due to that there's internal use of onMouseDown) | ||
*/ | ||
onMouseDown: React.PropTypes.func, | ||
}, | ||
componentWillUnmount: function() { | ||
// Remove any leftover event handlers | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
getDefaultProps: function () { | ||
return { | ||
axis: 'both', | ||
handle: null, | ||
cancel: null, | ||
grid: null, | ||
zIndex: NaN, | ||
onStart: emptyFunction, | ||
onDrag: emptyFunction, | ||
onStop: emptyFunction, | ||
onMouseDown: emptyFunction | ||
}; | ||
}, | ||
getInitialState: function () { | ||
return { | ||
// Whether or not we are currently dragging. | ||
dragging: false, | ||
// Offset between start top/left and mouse top/left while dragging. | ||
offsetX: 0, offsetY: 0, | ||
// Current transform x and y. | ||
clientX: 0, clientY: 0 | ||
}; | ||
}, | ||
handleDragStart: function (e) { | ||
// todo: write right implementation to prevent multitouch drag | ||
@@ -354,113 +385,112 @@ // prevent multi-touch events | ||
// Make it possible to attach event handlers on top of this one | ||
this.props.onMouseDown(e); | ||
// Make it possible to attach event handlers on top of this one | ||
this.props.onMouseDown(e); | ||
var node = this.getDOMNode(); | ||
// Short circuit if handle or cancel prop was provided and selector doesn't match | ||
if ((this.props.handle && !matchesSelector(e.target, this.props.handle)) || | ||
(this.props.cancel && matchesSelector(e.target, this.props.cancel))) { | ||
return; | ||
} | ||
// Short circuit if handle or cancel prop was provided and selector doesn't match | ||
if ((this.props.handle && !matchesSelector(e.target, this.props.handle)) || | ||
(this.props.cancel && matchesSelector(e.target, this.props.cancel))) { | ||
return; | ||
} | ||
var dragPoint = getControlPosition(e); | ||
// Initiate dragging | ||
this.setState({ | ||
dragging: true, | ||
offsetX: parseInt(dragPoint.clientX, 10), | ||
offsetY: parseInt(dragPoint.clientY, 10), | ||
startX: parseInt(node.style.left, 10) || 0, | ||
startY: parseInt(node.style.top, 10) || 0 | ||
}); | ||
// Initiate dragging. Set the current x and y as offsets | ||
// so we know how much we've moved during the drag. This allows us | ||
// to drag elements around even if they have been moved, without issue. | ||
this.setState({ | ||
dragging: true, | ||
offsetX: dragPoint.clientX - this.state.clientX, | ||
offsetY: dragPoint.clientY - this.state.clientY | ||
}); | ||
// Call event handler | ||
this.props.onStart(e, createUIEvent(this)); | ||
// Call event handler | ||
this.props.onStart(e, createUIEvent(this)); | ||
// Add event handlers | ||
addEvent(window, dragEventFor['move'], this.handleDrag); | ||
addEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
// Add event handlers | ||
addEvent(window, dragEventFor['move'], this.handleDrag); | ||
addEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
handleDragEnd: function (e) { | ||
// Short circuit if not currently dragging | ||
if (!this.state.dragging) { | ||
return; | ||
} | ||
handleDragEnd: function (e) { | ||
// Short circuit if not currently dragging | ||
if (!this.state.dragging) { | ||
return; | ||
} | ||
// Turn off dragging | ||
this.setState({ | ||
dragging: false | ||
}); | ||
// Turn off dragging | ||
this.setState({ | ||
dragging: false | ||
}); | ||
// Call event handler | ||
this.props.onStop(e, createUIEvent(this)); | ||
// Call event handler | ||
this.props.onStop(e, createUIEvent(this)); | ||
// Remove event handlers | ||
// Remove event handlers | ||
removeEvent(window, dragEventFor['move'], this.handleDrag); | ||
removeEvent(window, dragEventFor['end'], this.handleDragEnd); | ||
}, | ||
}, | ||
handleDrag: function (e) { | ||
handleDrag: function (e) { | ||
var dragPoint = getControlPosition(e); | ||
// Calculate top and left | ||
var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY)); | ||
// Calculate X and Y | ||
var clientX = dragPoint.clientX - this.state.offsetX; | ||
var clientY = dragPoint.clientY - this.state.offsetY; | ||
// Snap to grid if prop has been provided | ||
if (Array.isArray(this.props.grid)) { | ||
var directionX = clientX < parseInt(this.state.clientX, 10) ? -1 : 1; | ||
var directionY = clientY < parseInt(this.state.clientY, 10) ? -1 : 1; | ||
// Snap to grid if prop has been provided | ||
if (Array.isArray(this.props.grid)) { | ||
var coords = snapToGrid(this, clientX, clientY); | ||
clientX = coords[0], clientY = coords[1]; | ||
} | ||
clientX = Math.abs(clientX - parseInt(this.state.clientX, 10)) >= this.props.grid[0] | ||
? (parseInt(this.state.clientX, 10) + (this.props.grid[0] * directionX)) | ||
: this.state.clientX; | ||
// Update transform | ||
this.setState({ | ||
clientX: clientX, | ||
clientY: clientY | ||
}); | ||
clientY = Math.abs(clientY - parseInt(this.state.clientY, 10)) >= this.props.grid[1] | ||
? (parseInt(this.state.clientY, 10) + (this.props.grid[1] * directionY)) | ||
: this.state.clientY; | ||
} | ||
// Call event handler | ||
this.props.onDrag(e, createUIEvent(this)); | ||
}, | ||
// Update top and left | ||
this.setState({ | ||
clientX: clientX, | ||
clientY: clientY | ||
}); | ||
render: function () { | ||
// Create style object. We extend from existing styles so we don't | ||
// remove anything already set (like background, color, etc). | ||
var childStyle = this.props.children.props.style || {}; | ||
// Call event handler | ||
this.props.onDrag(e, createUIEvent(this)); | ||
}, | ||
// Add a CSS transform to move the element around. This allows us to move the element around | ||
// without worrying about whether or not it is relatively or absolutely positioned. | ||
// If the item you are dragging already has a transform set, wrap it in a <span> so <Draggable> | ||
// has a clean slate. | ||
var transform = createCSSTransform({ | ||
// Set left if horizontal drag is enabled | ||
x: canDragX(this) ? | ||
this.state.clientX : | ||
0, | ||
render: function () { | ||
var style = { | ||
// Set top if vertical drag is enabled | ||
top: canDragY(this) | ||
? this.state.clientY | ||
: this.state.startY, | ||
// Set top if vertical drag is enabled | ||
y: canDragY(this) ? | ||
this.state.clientY : | ||
0 | ||
}); | ||
var style = assign({}, userSelectStyle, childStyle, transform); | ||
// Set left if horizontal drag is enabled | ||
left: canDragX(this) | ||
? this.state.clientX | ||
: this.state.startX | ||
}; | ||
// Set zIndex if currently dragging and prop has been provided | ||
if (this.state.dragging && !isNaN(this.props.zIndex)) { | ||
style.zIndex = this.props.zIndex; | ||
} | ||
// Set zIndex if currently dragging and prop has been provided | ||
if (this.state.dragging && !isNaN(this.props.zIndex)) { | ||
style.zIndex = this.props.zIndex; | ||
} | ||
var className = classNames((this.props.children.props.className || ''), 'react-draggable', { | ||
'react-draggable-dragging': this.state.dragging, | ||
'react-draggable-dragged': this.state.dragged | ||
}); | ||
var className = 'react-draggable'; | ||
if (this.state.dragging) { | ||
className += ' react-draggable-dragging'; | ||
} | ||
// Reuse the child provided | ||
// This makes it flexible to use whatever element is wanted (div, ul, etc) | ||
return React.cloneElement(React.Children.only(this.props.children), { | ||
style: style, | ||
className: className, | ||
// Reuse the child provided | ||
// This makes it flexible to use whatever element is wanted (div, ul, etc) | ||
return React.addons.cloneWithProps(React.Children.only(this.props.children), { | ||
style: style, | ||
className: className, | ||
onMouseDown: this.handleDragStart, | ||
onTouchStart: function(ev){ | ||
onMouseDown: this.handleDragStart, | ||
onTouchStart: function(ev){ | ||
ev.preventDefault(); // prevent for scroll | ||
@@ -470,6 +500,6 @@ return this.handleDragStart.apply(this, arguments); | ||
onMouseUp: this.handleDragEnd, | ||
onTouchEnd: this.handleDragEnd | ||
}); | ||
} | ||
onMouseUp: this.handleDragEnd, | ||
onTouchEnd: this.handleDragEnd | ||
}); | ||
} | ||
}); |
{ | ||
"name": "react-draggable", | ||
"version": "0.4.2", | ||
"version": "0.5.0", | ||
"description": "React draggable component", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "script/test --browsers Firefox --single-run", | ||
"start": "script/build" | ||
"test": "make test", | ||
"dev": "make dev", | ||
"build": "make build" | ||
}, | ||
"browser": "dist/react-draggable.js", | ||
"repository": { | ||
@@ -27,3 +27,3 @@ "type": "git", | ||
"devDependencies": { | ||
"jsx-loader": "^0.12.0", | ||
"jsx-loader": "^0.13.2", | ||
"karma": "^0.12.19", | ||
@@ -35,8 +35,14 @@ "karma-chrome-launcher": "^0.1.4", | ||
"karma-webpack": "^1.2.1", | ||
"react": "^0.12.0", | ||
"reactify": "^0.17.1", | ||
"open": "0.0.5", | ||
"react": "^0.13.2", | ||
"semver": "^4.3.3", | ||
"static-server": "^2.0.0", | ||
"uglify-js": "^2.4.15", | ||
"webpack": "^1.3.2-beta8", | ||
"webpack-dev-server": "^1.4.7" | ||
}, | ||
"dependencies": { | ||
"classnames": "^1.2.2", | ||
"object-assign": "^2.0.0" | ||
} | ||
} | ||
} |
@@ -9,3 +9,3 @@ # react-draggable [![Build Status](https://travis-ci.org/mzabriskie/react-draggable.svg?branch=master)](https://travis-ci.org/mzabriskie/react-draggable) | ||
http://mzabriskie.github.io/react-draggable/example/ | ||
[View Demo](http://mzabriskie.github.io/react-draggable/example/) | ||
@@ -17,6 +17,20 @@ | ||
$ npm install react-draggable | ||
# or | ||
$ bower install react-draggable | ||
``` | ||
If you aren't using browserify/webpack, a | ||
[UMD version of react-draggable](http://mzabriskie.github.io/react-draggable/example/react-draggable.js) | ||
is updated in the `gh-pages` branch and used for the demo. You can generate it yourself from master by cloning this | ||
repository and running `$ make`. This will create umd dist files in the `dist/` folder. | ||
## 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. | ||
## Example | ||
@@ -51,2 +65,4 @@ | ||
// | ||
// The element is moved from its current position using absolute positioning. | ||
// | ||
// `axis` determines which axis the draggable can move. | ||
@@ -63,4 +79,2 @@ // - 'both' allows movement horizontally and vertically (default). | ||
// | ||
// `start` specifies the x and y that the dragged item should start at | ||
// | ||
// `zIndex` specifies the zIndex to use while dragging. | ||
@@ -78,3 +92,2 @@ // | ||
grid={[25, 25]} | ||
start={{x: 25, y: 25}} | ||
zIndex={100} | ||
@@ -99,6 +112,6 @@ onStart={this.handleStart} | ||
- Fork the project | ||
- `$ npm install && npm start` | ||
- Make changes, webpack will watch and rebuild as you make changes | ||
- Run the project in development mode: `$ make dev` | ||
- Make changes. | ||
- Add appropriate tests | ||
- `$ npm test` | ||
- `$ make test` | ||
- If tests don't pass, make them pass. | ||
@@ -108,4 +121,10 @@ - Update README with appropriate docs. | ||
## Release checklist | ||
- Update CHANGELOG | ||
- `make release-patch`, `make release-minor`, or `make-release-major` | ||
- `make publish` | ||
## License | ||
MIT |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
1
124
22206
2
14
8
463
1
+ Addedclassnames@^1.2.2
+ Addedobject-assign@^2.0.0
+ Addedclassnames@1.2.2(transitive)
+ Addedobject-assign@2.1.1(transitive)