react-draggable
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -9,2 +9,10 @@ # Changelog | ||
- Fixing dragging not stopping on mouseup in some cases | ||
- Fixing dragging not stopping on mouseup in some cases | ||
### 0.2.0 (Sep 10, 2014) | ||
- Adding support for snapping to a grid | ||
- Adding support for specifying start position | ||
- Ensure event handlers are destroyed on unmount | ||
- Adding browserify support | ||
- Adding bower support |
'use strict'; | ||
/** @jsx React.DOM */ | ||
var React = require('react/addons'), | ||
invariant = require('react/lib/invariant'), | ||
emptyFunction = require('react/lib/emptyFunction'); | ||
var React = require('react/addons'); | ||
var emptyFunction = require('react/lib/emptyFunction'); | ||
@@ -129,2 +128,40 @@ function createUIEvent(draggable) { | ||
/** | ||
* `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` 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, | ||
/** | ||
* `zIndex` specifies the zIndex to use while dragging. | ||
@@ -206,5 +243,17 @@ * | ||
*/ | ||
onStop: React.PropTypes.func | ||
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, 'mousemove', this.handleMouseMove); | ||
removeEvent(window, 'mouseup', this.handleMouseUp); | ||
}, | ||
getDefaultProps: function () { | ||
@@ -215,6 +264,12 @@ return { | ||
cancel: null, | ||
grid: null, | ||
start: { | ||
x: 0, | ||
y: 0 | ||
}, | ||
zIndex: NaN, | ||
onStart: emptyFunction, | ||
onDrag: emptyFunction, | ||
onStop: emptyFunction | ||
onStop: emptyFunction, | ||
onMouseDown: emptyFunction | ||
}; | ||
@@ -225,19 +280,23 @@ }, | ||
return { | ||
// Whether or not currently dragging | ||
dragging: false, | ||
// Start top/left of this.getDOMNode() | ||
startX: 0, startY: 0, | ||
// Offset between start top/left and mouse top/left | ||
offsetX: 0, offsetY: 0, | ||
clientX: 0, clientY: 0 | ||
// Current top/left of this.getDOMNode() | ||
clientX: this.props.start.x, clientY: this.props.start.y | ||
}; | ||
}, | ||
componentWillMount: function () { | ||
invariant( | ||
React.Children.count(this.props.children) === 1, | ||
'There should only be a single child element within Draggable.' | ||
); | ||
}, | ||
handleMouseDown: function (e) { | ||
// Make it possible to attach event handlers on top of this one | ||
this.props.onMouseDown(e); | ||
handleMouseDown: function (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)) || | ||
@@ -248,2 +307,3 @@ (this.props.cancel && matchesSelector(e.target, this.props.cancel))) { | ||
// Initiate dragging | ||
this.setState({ | ||
@@ -257,4 +317,6 @@ dragging: true, | ||
// Call event handler | ||
this.props.onStart(e, createUIEvent(this)); | ||
// Add event handlers | ||
addEvent(window, 'mousemove', this.handleMouseMove); | ||
@@ -265,2 +327,3 @@ addEvent(window, 'mouseup', this.handleMouseUp); | ||
handleMouseUp: function (e) { | ||
// Short circuit if not currently dragging | ||
if (!this.state.dragging) { | ||
@@ -270,2 +333,3 @@ return; | ||
// Turn off dragging | ||
this.setState({ | ||
@@ -275,4 +339,6 @@ dragging: false | ||
// Call event handler | ||
this.props.onStop(e, createUIEvent(this)); | ||
// Remove event handlers | ||
removeEvent(window, 'mousemove', this.handleMouseMove); | ||
@@ -283,7 +349,24 @@ removeEvent(window, 'mouseup', this.handleMouseUp); | ||
handleMouseMove: function (e) { | ||
// Calculate top and left | ||
var clientX = (this.state.startX + (e.clientX - this.state.offsetX)); | ||
var clientY = (this.state.startY + (e.clientY - this.state.offsetY)); | ||
// Snap to grid if prop has been provided | ||
if (Array.isArray(this.props.grid)) { | ||
clientX = Math.abs(clientX - this.state.clientX) >= this.props.grid[0] | ||
? clientX | ||
: this.state.clientX; | ||
clientY = Math.abs(clientY - this.state.clientY) >= this.props.grid[1] | ||
? clientY | ||
: this.state.clientY; | ||
} | ||
// Update top and left | ||
this.setState({ | ||
clientX: (this.state.startX + (e.clientX - this.state.offsetX)), | ||
clientY: (this.state.startY + (e.clientY - this.state.offsetY)) | ||
clientX: clientX, | ||
clientY: clientY | ||
}); | ||
// Call event handler | ||
this.props.onDrag(e, createUIEvent(this)); | ||
@@ -294,6 +377,14 @@ }, | ||
var style = { | ||
top: canDragY(this) ? this.state.clientY : this.state.startY, | ||
left: canDragX(this) ? this.state.clientX : this.state.startX | ||
// Set top if vertical drag is enabled | ||
top: canDragY(this) | ||
? this.state.clientY | ||
: this.state.startY, | ||
// 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)) { | ||
@@ -305,16 +396,9 @@ style.zIndex = this.props.zIndex; | ||
// This makes it flexible to use whatever element is wanted (div, ul, etc) | ||
var child = null; | ||
React.Children.forEach(this.props.children, function (c) { | ||
if (child === null) { | ||
child = React.addons.cloneWithProps(c, { | ||
style: style, | ||
className: 'react-draggable', | ||
onMouseUp: this.handleMouseUp, | ||
onMouseDown: this.handleMouseDown | ||
}); | ||
} | ||
}, this); | ||
return child; | ||
return React.addons.cloneWithProps(React.Children.only(this.props.children), { | ||
style: style, | ||
className: 'react-draggable', | ||
onMouseUp: this.handleMouseUp, | ||
onMouseDown: this.handleMouseDown | ||
}); | ||
} | ||
}); |
{ | ||
"name": "react-draggable", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "React draggable component", | ||
"main": "lib/main.js", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"build": "script/build" | ||
"test": "script/test --browsers Firefox --single-run", | ||
"start": "script/build" | ||
}, | ||
"browserify": { | ||
"transform": [ | ||
"reactify" | ||
] | ||
}, | ||
"repository": { | ||
@@ -16,3 +21,4 @@ "type": "git", | ||
"react", | ||
"draggable" | ||
"draggable", | ||
"react-component" | ||
], | ||
@@ -25,6 +31,17 @@ "author": "Matt Zabriskie", | ||
"homepage": "https://github.com/mzabriskie/react-draggable", | ||
"dependencies": { | ||
"react": "^0.11.1" | ||
}, | ||
"devDependencies": { | ||
"react": "^0.11.0", | ||
"jsx-loader": "^0.11.0" | ||
"jsx-loader": "^0.11.0", | ||
"karma": "^0.12.19", | ||
"karma-cli": "0.0.4", | ||
"karma-jasmine": "^0.1.5", | ||
"karma-chrome-launcher": "^0.1.4", | ||
"karma-firefox-launcher": "^0.1.3", | ||
"webpack": "^1.3.2-beta8", | ||
"webpack-dev-server": "^1.4.7", | ||
"karma-webpack": "^1.2.1", | ||
"uglify-js": "^2.4.15" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# react-draggable | ||
# react-draggable [![Build Status](https://travis-ci.org/mzabriskie/react-draggable.svg?branch=master)](https://travis-ci.org/mzabriskie/react-draggable) | ||
@@ -8,3 +8,5 @@ React draggable component | ||
```bash | ||
npm install react-draggable | ||
$ npm install react-draggable | ||
# or | ||
$ bower install react-draggable | ||
``` | ||
@@ -54,2 +56,6 @@ | ||
// | ||
// `grid` specifies the x and y that dragging should snap to. | ||
// | ||
// `start` specifies the x and y that the dragged item should start at | ||
// | ||
// `zIndex` specifies the zIndex to use while dragging. | ||
@@ -66,2 +72,4 @@ // | ||
handle=".handle" | ||
grid={[25, 25]} | ||
start={{x: 25, y: 25}} | ||
zIndex={100} | ||
@@ -83,4 +91,15 @@ onStart={this.handleStart} | ||
## Contributing | ||
- Fork the project | ||
- `$ npm install && npm start` | ||
- Make changes, webpack will watch and rebuild as you make changes | ||
- Add appropriate tests | ||
- `$ npm test` | ||
- If tests don't pass, make them pass. | ||
- Update README with appropriate docs. | ||
- Commit and PR | ||
## 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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances 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
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
65126
946
101
1
10
11
4
1
+ Addedreact@^0.11.1
+ Addedamdefine@1.0.1(transitive)
+ Addedbase62@0.1.1(transitive)
+ Addedenvify@2.0.1(transitive)
+ Addedesprima-fb@3001.1.0-dev-harmony-fb(transitive)
+ Addedjstransform@3.0.0(transitive)
+ Addedobject-keys@0.4.0(transitive)
+ Addedreact@0.11.2(transitive)
+ Addedsource-map@0.1.31(transitive)
+ Addedthrough@2.3.8(transitive)
+ Addedxtend@2.1.2(transitive)