react-draggable
Advanced tools
Comparing version
{ | ||
"name": "react-draggable", | ||
"version": "2.0.0-beta2", | ||
"version": "2.0.0-beta3", | ||
"homepage": "https://github.com/mzabriskie/react-draggable", | ||
@@ -5,0 +5,0 @@ "authors": [ |
# Changelog | ||
### 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. | ||
### 2.0.0-beta2 (Apr 14, 2016) | ||
@@ -4,0 +9,0 @@ |
@@ -114,2 +114,5 @@ (function webpackUniversalModuleDefinition(root, factory) { | ||
/*:: import type {DraggableEventHandler} from './utils/types';*/ | ||
// | ||
@@ -119,2 +122,10 @@ // Define <Draggable> | ||
/*:: type DraggableState = { | ||
dragging: boolean, | ||
dragged: boolean, | ||
x: number, y: number, | ||
slackX: number, slackY: number, | ||
isElementSVG: boolean | ||
};*/ | ||
var Draggable = function (_React$Component) { | ||
@@ -165,3 +176,3 @@ _inherits(Draggable, _React$Component); | ||
var newState = { | ||
var newState /*: $Shape<DraggableState>*/ = { | ||
x: uiData.x, | ||
@@ -220,3 +231,3 @@ y: uiData.y | ||
var newState = { | ||
var newState /*: $Shape<DraggableState>*/ = { | ||
dragging: false, | ||
@@ -261,3 +272,3 @@ slackX: 0, | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
value: function componentWillReceiveProps(nextProps /*: Object*/) { | ||
// Set x/y if position has changed | ||
@@ -541,4 +552,7 @@ if (nextProps.position && (!this.props.position || nextProps.position.x !== this.props.position.x || nextProps.position.y !== this.props.position.y)) { | ||
/*:: import type {ControlPosition} from './types';*/ | ||
var matchesSelectorFunc = ''; | ||
function matchesSelector(el, selector) { | ||
function matchesSelector(el /*: Node*/, selector /*: string*/) /*: boolean*/ { | ||
if (!matchesSelectorFunc) { | ||
@@ -555,3 +569,3 @@ matchesSelectorFunc = (0, _shims.findInArray)(['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'], function (method) { | ||
function addEvent(el, event, handler) { | ||
function addEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/) /*: void*/ { | ||
if (!el) { | ||
@@ -570,3 +584,3 @@ return; | ||
function removeEvent(el, event, handler) { | ||
function removeEvent(el /*: ?Node*/, event /*: string*/, handler /*: Function*/) /*: void*/ { | ||
if (!el) { | ||
@@ -585,3 +599,3 @@ return; | ||
function outerHeight(node) { | ||
function outerHeight(node /*: HTMLElement*/) /*: number*/ { | ||
// This is deliberately excluding margin for our calculations, since we are using | ||
@@ -596,3 +610,3 @@ // offsetTop which is including margin. See getBoundPosition | ||
function outerWidth(node) { | ||
function outerWidth(node /*: HTMLElement*/) /*: number*/ { | ||
// This is deliberately excluding margin for our calculations, since we are using | ||
@@ -606,3 +620,3 @@ // offsetLeft which is including margin. See getBoundPosition | ||
} | ||
function innerHeight(node) { | ||
function innerHeight(node /*: HTMLElement*/) /*: number*/ { | ||
var height = node.clientHeight; | ||
@@ -615,3 +629,3 @@ var computedStyle = window.getComputedStyle(node); | ||
function innerWidth(node) { | ||
function innerWidth(node /*: HTMLElement*/) /*: number*/ { | ||
var width = node.clientWidth; | ||
@@ -625,3 +639,3 @@ var computedStyle = window.getComputedStyle(node); | ||
// Get from offsetParent | ||
function offsetXYFromParentOf(e, node) { | ||
function offsetXYFromParentOf(e /*: MouseEvent*/, node /*: HTMLElement & {offsetParent: HTMLElement}*/) /*: ControlPosition*/ { | ||
var evt = e.targetTouches ? e.targetTouches[0] : e; | ||
@@ -638,3 +652,3 @@ | ||
function createCSSTransform(_ref) { | ||
function createCSSTransform(_ref) /*: Object*/ { | ||
var x = _ref.x; | ||
@@ -647,3 +661,3 @@ var y = _ref.y; | ||
function createSVGTransform(_ref3) { | ||
function createSVGTransform(_ref3) /*: string*/ { | ||
var x = _ref3.x; | ||
@@ -672,4 +686,4 @@ var y = _ref3.y; | ||
function styleHacks() { | ||
var childStyle = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
function styleHacks() /*: Object*/ { | ||
var childStyle /*: Object*/ = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; | ||
@@ -699,3 +713,3 @@ // Workaround IE pointer events; see #51 | ||
// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc | ||
function findInArray(array, callback) { | ||
function findInArray(array /*: Array<any>*/, callback /*: Function*/) /*: any*/ { | ||
for (var i = 0, length = array.length; i < length; i++) { | ||
@@ -706,15 +720,15 @@ if (callback.apply(callback, [array[i], i, array])) return array[i]; | ||
function isFunction(func) { | ||
function isFunction(func /*: any*/) /*: boolean*/ { | ||
return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]'; | ||
} | ||
function isNum(num) { | ||
function isNum(num /*: any*/) /*: boolean*/ { | ||
return typeof num === 'number' && !isNaN(num); | ||
} | ||
function int(a) { | ||
function int(a /*: string*/) /*: number*/ { | ||
return parseInt(a, 10); | ||
} | ||
function dontSetMe(props, propName, componentName) { | ||
function dontSetMe(props /*: Object*/, propName /*: string*/, componentName /*: string*/) { | ||
if (props[propName]) { | ||
@@ -739,4 +753,4 @@ return new Error('Invalid prop ' + propName + ' passed to ' + componentName + ' - do not set this, set it on the child.'); | ||
var prefixes = ['Moz', 'Webkit', 'O', 'ms']; | ||
function getPrefix() { | ||
var prop = arguments.length <= 0 || arguments[0] === undefined ? 'transform' : arguments[0]; | ||
function getPrefix() /*: string*/ { | ||
var prop /*: string*/ = arguments.length <= 0 || arguments[0] === undefined ? 'transform' : arguments[0]; | ||
@@ -759,11 +773,11 @@ // Checking specifically for 'window.document' is for pseudo-browser server-side | ||
function browserPrefixToKey(prop, prefix) { | ||
function browserPrefixToKey(prop /*: string*/, prefix /*: string*/) /*: string*/ { | ||
return prefix ? '' + prefix + kebabToTitleCase(prop) : prop; | ||
} | ||
function browserPrefixToStyle(prop, prefix) { | ||
function browserPrefixToStyle(prop /*: string*/, prefix /*: string*/) /*: string*/ { | ||
return prefix ? '-' + prefix.toLowerCase() + '-' + prop : prop; | ||
} | ||
function kebabToTitleCase(str) { | ||
function kebabToTitleCase(str /*: string*/) /*: string*/ { | ||
var out = ''; | ||
@@ -816,3 +830,6 @@ var shouldCapitalize = true; | ||
function getBoundPosition(draggable, x, y) { | ||
/*:: import type Draggable from '../Draggable';*/ | ||
/*:: import type {Bounds, ControlPosition, DraggableData} from './types';*/ | ||
/*:: import type DraggableCore from '../DraggableCore';*/ | ||
function getBoundPosition(draggable /*: Draggable*/, x /*: number*/, y /*: number*/) /*: [number, number]*/ { | ||
// If no bounds, short-circuit and move on | ||
@@ -857,3 +874,3 @@ if (!draggable.props.bounds) return [x, y]; | ||
function snapToGrid(grid, pendingX, pendingY) { | ||
function snapToGrid(grid /*: [number, number]*/, pendingX /*: number*/, pendingY /*: number*/) /*: [number, number]*/ { | ||
var x = Math.round(pendingX / grid[0]) * grid[0]; | ||
@@ -864,7 +881,7 @@ var y = Math.round(pendingY / grid[1]) * grid[1]; | ||
function canDragX(draggable) { | ||
function canDragX(draggable /*: Draggable*/) /*: boolean*/ { | ||
return draggable.props.axis === 'both' || draggable.props.axis === 'x'; | ||
} | ||
function canDragY(draggable) { | ||
function canDragY(draggable /*: Draggable*/) /*: boolean*/ { | ||
return draggable.props.axis === 'both' || draggable.props.axis === 'y'; | ||
@@ -874,3 +891,3 @@ } | ||
// Get {x, y} positions from event. | ||
function getControlPosition(e, draggableCore) { | ||
function getControlPosition(e /*: MouseEvent*/, draggableCore /*: DraggableCore*/) /*: ControlPosition*/ { | ||
return (0, _domFns.offsetXYFromParentOf)(e, _reactDom2.default.findDOMNode(draggableCore)); | ||
@@ -880,3 +897,3 @@ } | ||
// Create an data object exposed by <DraggableCore>'s events | ||
function createCoreData(draggable, x, y) { | ||
function createCoreData(draggable /*: DraggableCore*/, x /*: number*/, y /*: number*/) /*: DraggableData*/ { | ||
// State changes are often (but not always!) async. We want the latest value. | ||
@@ -906,3 +923,3 @@ var state = draggable._pendingState || draggable.state; | ||
// Create an data exposed by <Draggable>'s events | ||
function createDraggableData(draggable, coreData) { | ||
function createDraggableData(draggable /*: Draggable*/, coreData /*: DraggableData*/) /*: DraggableData*/ { | ||
return { | ||
@@ -920,3 +937,3 @@ node: coreData.node, | ||
// A lot faster than stringify/parse | ||
function cloneBounds(bounds) { | ||
function cloneBounds(bounds /*: Bounds*/) /*: Bounds*/ { | ||
return { | ||
@@ -967,2 +984,3 @@ left: bounds.left, | ||
// Simple abstraction for dragging events names. | ||
/*:: import type {EventHandler} from './utils/types';*/ | ||
var eventsFor = { | ||
@@ -991,2 +1009,9 @@ touch: { | ||
/*:: type CoreState = { | ||
dragging: boolean, | ||
lastX: number, | ||
lastY: number, | ||
touchIdentifier: number | ||
};*/ | ||
var DraggableCore = function (_React$Component) { | ||
@@ -993,0 +1018,0 @@ _inherits(DraggableCore, _React$Component); |
{ | ||
"name": "react-draggable", | ||
"version": "2.0.0-beta2", | ||
"version": "2.0.0-beta3", | ||
"description": "React draggable component", | ||
@@ -34,2 +34,3 @@ "main": "dist/react-draggable.js", | ||
"babel-loader": "^6.2.2", | ||
"babel-plugin-transform-flow-comments": "^6.7.0", | ||
"babel-preset-es2015": "^6.5.0", | ||
@@ -36,0 +37,0 @@ "babel-preset-react": "^6.5.0", |
134
README.md
@@ -1,12 +0,29 @@ | ||
# React-Draggable [](https://travis-ci.org/mzabriskie/react-draggable) | ||
# React-Draggable [](https://travis-ci.org/mzabriskie/react-draggable) []() | ||
A simple component for making elements draggable. | ||
[View the Changelog](CHANGELOG.md) | ||
```js | ||
<Draggable> | ||
<div>I can now be moved around!</div> | ||
</Draggable> | ||
``` | ||
### Demo | ||
- [Demo](http://mzabriskie.github.io/react-draggable/example/) | ||
- [Changelog](CHANGELOG.md) | ||
[View Demo](http://mzabriskie.github.io/react-draggable/example/) | ||
------ | ||
#### Technical Documentation | ||
- [Installing](#installing) | ||
- [Exports](#exports) | ||
- [Draggable](#draggable) | ||
- [Draggable Usage](#draggable-usage) | ||
- [Draggable API](#draggable-api) | ||
- [Controlled vs. Uncontrolled](#controlled-vs-uncontrolled) | ||
- [DraggableCore](#draggablecore) | ||
- [DraggableCore API](#draggablecore-api) | ||
### Installing | ||
@@ -52,8 +69,49 @@ | ||
### Draggable Usage | ||
View the [Demo](http://mzabriskie.github.io/react-draggable/example/) and its | ||
[source](/example/index.html) for more. | ||
```js | ||
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 draggable to whatever element is supplied as `this.props.children`. | ||
**Note**: Only a single element is allowed or an Error will be thrown. | ||
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 | ||
@@ -65,9 +123,12 @@ for the following props: | ||
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](https://facebook.github.io/react/docs/transferring-props.html) helpful. | ||
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](https://facebook.github.io/react/docs/transferring-props.html). | ||
Props: | ||
#### `<Draggable>` Props: | ||
```js | ||
// | ||
// Types: | ||
// | ||
type DraggableEventHandler = (e: Event, data: DraggableData) => void | false; | ||
@@ -81,2 +142,6 @@ type DraggableData = { | ||
}; | ||
// | ||
// Props: | ||
// | ||
{ | ||
@@ -125,3 +190,3 @@ // If set to `true`, will allow dragging on non left-button clicks. | ||
// disabled status. | ||
onMouseDown: (e: MouseEvent) => boolean, | ||
onMouseDown: (e: MouseEvent) => void, | ||
@@ -150,49 +215,2 @@ // Called when dragging starts. If `false` is returned any handler, | ||
### Draggable Usage | ||
```js | ||
var React = require('react'),; | ||
var ReactDOM = require('react-dom'); | ||
var 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" | ||
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); | ||
``` | ||
## Controlled vs. Uncontrolled | ||
@@ -199,0 +217,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
207130
1.43%1263
1.53%289
6.64%29
3.57%