diff --git a/dist/react-draggable.js b/dist/react-draggable.js index 95cba711..e3afa914 100644 --- a/dist/react-draggable.js +++ b/dist/react-draggable.js @@ -86,24 +86,68 @@ return /******/ (function(modules) { // webpackBootstrap draggable.props.axis === 'x'; } - function isFunction(fn) { - return typeof fn === 'function'; + function isFunction(func) { + return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]' + } + + // @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc + function findInArray(array, callback) { + for (var i = 0, element = array[i], length = array.length; i < length; i++) { + if (callback.apply(callback, [element, i, array])) return element; + } } function matchesSelector(el, selector) { - if (isFunction(el.matches)) { - return el.matches(selector); - } else if (isFunction(el.webkitMatchesSelector)) { - return el.webkitMatchesSelector(selector); - } else if (isFunction(el.mozMatchesSelector)) { - return el.mozMatchesSelector(selector); - } else if (isFunction(el.msMatchesSelector)) { - return el.msMatchesSelector(selector); - } else if (isFunction(el.oMatchesSelector)) { - return el.oMatchesSelector(selector); - } else if (isFunction(el.webkitMatchesSelector)) { - return el.webkitMatchesSelector(selector); - } + var method = findInArray([ + 'matches', + 'webkitMatchesSelector', + 'mozMatchesSelector', + 'msMatchesSelector', + 'oMatchesSelector' + ], function(method){ + return isFunction(el[method]); + }); + + return el[method].call(el, selector); + } + + // @credits: http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886 + var isTouchDevice = 'ontouchstart' in window // works on most browsers + || 'onmsgesturechange' in window; // works on ie10 on ms surface + + // look ::handleDragStart + //function isMultiTouch(e) { + // return e.touches && Array.isArray(e.touches) && e.touches.length > 1 + //} + + /** + * simple abstraction for dragging events names + * */ + var dragEventFor = (function () { + var eventsFor = { + touch: { + start: 'touchstart', + move: 'touchmove', + end: 'touchend' + }, + mouse: { + start: 'mousedown', + move: 'mousemove', + end: 'mouseup' + } + }; + return eventsFor[isTouchDevice ? 'touch' : 'mouse']; + })(); + + /** + * get {clientX, clientY} positions of control + * */ + function getControlPosition(e) { + var position = !isTouchDevice ? e : e.touches[0]; + return { + clientX: position.clientX, + clientY: position.clientY + } } function addEvent(el, event, handler) { @@ -313,8 +357,8 @@ return /******/ (function(modules) { // webpackBootstrap componentWillUnmount: function() { // Remove any leftover event handlers - removeEvent(window, 'mousemove', this.handleMouseMove); - removeEvent(window, 'mouseup', this.handleMouseUp); + removeEvent(window, dragEventFor['move'], this.handleDrag); + removeEvent(window, dragEventFor['end'], this.handleDragEnd); }, getDefaultProps: function () { @@ -351,7 +395,14 @@ return /******/ (function(modules) { // webpackBootstrap }; }, - handleMouseDown: function (e) { + handleDragStart: function (e) { + // todo: write right implementation to prevent multitouch drag + // prevent multi-touch events + // if (isMultiTouch(e)) { + // this.handleDragEnd.apply(e, arguments); + // return + // } + // Make it possible to attach event handlers on top of this one this.props.onMouseDown(e); @@ -363,11 +414,13 @@ return /******/ (function(modules) { // webpackBootstrap return; } + var dragPoint = getControlPosition(e); + // Initiate dragging this.setState({ dragging: true, - offsetX: e.clientX, - offsetY: e.clientY, + offsetX: dragPoint.clientX, + offsetY: dragPoint.clientY, startX: parseInt(node.style.left, 10) || 0, startY: parseInt(node.style.top, 10) || 0 }); @@ -376,11 +429,11 @@ return /******/ (function(modules) { // webpackBootstrap this.props.onStart(e, createUIEvent(this)); // Add event handlers - addEvent(window, 'mousemove', this.handleMouseMove); - addEvent(window, 'mouseup', this.handleMouseUp); + addEvent(window, dragEventFor['move'], this.handleDrag); + addEvent(window, dragEventFor['end'], this.handleDragEnd); }, - handleMouseUp: function (e) { + handleDragEnd: function (e) { // Short circuit if not currently dragging if (!this.state.dragging) { return; @@ -395,14 +448,16 @@ return /******/ (function(modules) { // webpackBootstrap this.props.onStop(e, createUIEvent(this)); // Remove event handlers - removeEvent(window, 'mousemove', this.handleMouseMove); - removeEvent(window, 'mouseup', this.handleMouseUp); + removeEvent(window, dragEventFor['move'], this.handleDrag); + removeEvent(window, dragEventFor['end'], this.handleDragEnd); }, - handleMouseMove: function (e) { + handleDrag: function (e) { + var dragPoint = getControlPosition(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)); + var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX)); + var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY)); // Snap to grid if prop has been provided if (Array.isArray(this.props.grid)) { @@ -448,8 +503,15 @@ return /******/ (function(modules) { // webpackBootstrap return React.addons.cloneWithProps(React.Children.only(this.props.children), { style: style, className: 'react-draggable', - onMouseUp: this.handleMouseUp, - onMouseDown: this.handleMouseDown + + onMouseDown: this.handleDragStart, + onTouchStart: function(ev){ + ev.preventDefault(); // prevent for scroll + return this.handleDragStart.apply(this, arguments); + }.bind(this), + + onMouseUp: this.handleDragEnd, + onTouchEnd: this.handleDragEnd }); } }); @@ -642,6 +704,6 @@ return /******/ (function(modules) { // webpackBootstrap /***/ } /******/ ]) -}) +}); //# sourceMappingURL=react-draggable.map \ No newline at end of file diff --git a/dist/react-draggable.map b/dist/react-draggable.map index cd4c2589..1529854f 100644 --- a/dist/react-draggable.map +++ b/dist/react-draggable.map @@ -1 +1 @@ -{"version":3,"file":"./dist/react-draggable.js","sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap a117b2e2f53821cee8d1","webpack:///./index.js","webpack:///./lib/draggable.js","webpack:///external \"React\"","webpack:///./~/react/lib/emptyFunction.js","webpack:///./~/react/lib/copyProperties.js","webpack:///(webpack)/~/node-libs-browser/~/process/browser.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,wC;;;;;;CCtCA;;;;;CCAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA,YAAW,QAAQ;AACnB;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA,YAAW,QAAQ;AACnB;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAmC,SAAS;AAC5C;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,cAAc;AACnD,oDAAmD,WAAW;AAC9D;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,IAAI;AACzC;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;AACH;AACA,EAAC;;;;;CCvYD,gD;;;;CCAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gCAA+B,aAAa,EAAE;AAC9C,uCAAsC,YAAY;AAClD,EAAC;;AAED;;;;;CC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;CCrDA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,4BAA2B;AAC3B;AACA;AACA","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"React\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"React\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ReactDraggable\"] = factory(require(\"React\"));\n\telse\n\t\troot[\"ReactDraggable\"] = factory(root[\"React\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap a117b2e2f53821cee8d1\n **/","module.exports = require('./lib/draggable');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./index.js\n ** module id = 0\n ** module chunks = 0\n **/","'use strict';\n\n/** @jsx React.DOM */\nvar React = require('react/addons');\nvar emptyFunction = require('react/lib/emptyFunction');\n\nfunction createUIEvent(draggable) {\n\treturn {\n\t\tposition: {\n\t\t\ttop: draggable.state.clientY,\n\t\t\tleft: draggable.state.clientX\n\t\t}\n\t};\n}\n\nfunction canDragY(draggable) {\n\treturn draggable.props.axis === 'both' ||\n\t\t\tdraggable.props.axis === 'y';\n}\n\nfunction canDragX(draggable) {\n\treturn draggable.props.axis === 'both' ||\n\t\t\tdraggable.props.axis === 'x';\n}\n\nfunction isFunction(fn) {\n\treturn typeof fn === 'function';\n}\n\nfunction matchesSelector(el, selector) {\n\tif (isFunction(el.matches)) {\n\t\treturn el.matches(selector);\n\t} else if (isFunction(el.webkitMatchesSelector)) {\n\t\treturn el.webkitMatchesSelector(selector);\n\t} else if (isFunction(el.mozMatchesSelector)) {\n\t\treturn el.mozMatchesSelector(selector);\n\t} else if (isFunction(el.msMatchesSelector)) {\n\t\treturn el.msMatchesSelector(selector);\n\t} else if (isFunction(el.oMatchesSelector)) {\n\t\treturn el.oMatchesSelector(selector);\n\t} else if (isFunction(el.webkitMatchesSelector)) {\n\t\treturn el.webkitMatchesSelector(selector);\n\t}\n}\n\nfunction addEvent(el, event, handler) {\n\tif (!el) { return; }\n\tif (el.attachEvent) {\n\t\tel.attachEvent('on' + event, handler);\n\t} else if (el.addEventListener) {\n\t\tel.addEventListener(event, handler, true);\n\t} else {\n\t\tel['on' + event] = handler;\n\t}\n}\n\nfunction removeEvent(el, event, handler) {\n\tif (!el) { return; }\n\tif (el.detachEvent) {\n\t\tel.detachEvent('on' + event, handler);\n\t} else if (el.removeEventListener) {\n\t\tel.removeEventListener(event, handler, true);\n\t} else {\n\t\tel['on' + event] = null;\n\t}\n}\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Draggable',\n\n\tpropTypes: {\n\t\t/**\n\t\t * `axis` determines which axis the draggable can move.\n\t\t *\n\t\t * 'both' allows movement horizontally and vertically.\n\t\t * 'x' limits movement to horizontal axis.\n\t\t * 'y' limits movement to vertical axis.\n\t\t *\n\t\t * Defaults to 'both'.\n\t\t */\n\t\taxis: React.PropTypes.oneOf(['both', 'x', 'y']),\n\n\t\t/**\n\t\t * `handle` specifies a selector to be used as the handle that initiates drag.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t \treturn (\n\t\t * \t \t \t\n\t\t * \t \t \t
\n\t\t * \t \t \t
Click me to drag
\n\t\t * \t \t \t
This is some other content
\n\t\t * \t \t \t
\n\t\t * \t \t\t
\n\t\t * \t \t);\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\thandle: React.PropTypes.string,\n\n\t\t/**\n\t\t * `cancel` specifies a selector to be used to prevent drag initialization.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return(\n\t\t * \t \n\t\t * \t
\n\t\t * \t \t
You can't drag from here
\n\t\t *\t\t\t\t\t\t
Dragging here works fine
\n\t\t * \t
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tcancel: React.PropTypes.string,\n\n\t\t/**\n\t\t * `grid` specifies the x and y that dragging should snap to.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I snap to a 25 x 25 grid
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tgrid: React.PropTypes.arrayOf(React.PropTypes.number),\n\n\t\t/**\n\t\t * `start` specifies the x and y that the dragged item should start at\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I start with left: 25px; top: 25px;
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tstart: React.PropTypes.object,\n\n\t\t/**\n\t\t * `zIndex` specifies the zIndex to use while dragging.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I have a zIndex
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tzIndex: React.PropTypes.number,\n\n\t\t/**\n\t\t * Called when dragging starts.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonStart: React.PropTypes.func,\n\n\t\t/**\n\t\t * Called while dragging.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonDrag: React.PropTypes.func,\n\n\t\t/**\n\t\t * Called when dragging stops.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonStop: React.PropTypes.func,\n\n\t\t/**\n\t\t * 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)\n\t\t *\n\t\t */\n\t\tonMouseDown: React.PropTypes.func\n\t},\n\n\tcomponentWillUnmount: function() {\n\t\t// Remove any leftover event handlers\n\t\tremoveEvent(window, 'mousemove', this.handleMouseMove);\n\t\tremoveEvent(window, 'mouseup', this.handleMouseUp);\n\t},\n\n\tgetDefaultProps: function () {\n\t\treturn {\n\t\t\taxis: 'both',\n\t\t\thandle: null,\n\t\t\tcancel: null,\n\t\t\tgrid: null,\n\t\t\tstart: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0\n\t\t\t},\n\t\t\tzIndex: NaN,\n\t\t\tonStart: emptyFunction,\n\t\t\tonDrag: emptyFunction,\n\t\t\tonStop: emptyFunction,\n\t\t\tonMouseDown: emptyFunction\n\t\t};\n\t},\n\n\tgetInitialState: function () {\n\t\treturn {\n\t\t\t// Whether or not currently dragging\n\t\t\tdragging: false,\n\n\t\t\t// Start top/left of this.getDOMNode()\n\t\t\tstartX: 0, startY: 0,\n\n\t\t\t// Offset between start top/left and mouse top/left\n\t\t\toffsetX: 0, offsetY: 0,\n\n\t\t\t// Current top/left of this.getDOMNode()\n\t\t\tclientX: this.props.start.x, clientY: this.props.start.y\n\t\t};\n\t},\n\n\thandleMouseDown: function (e) {\n\t\t// Make it possible to attach event handlers on top of this one\n\t\tthis.props.onMouseDown(e);\n\n\t\tvar node = this.getDOMNode();\n\n\t\t// Short circuit if handle or cancel prop was provided and selector doesn't match\n\t\tif ((this.props.handle && !matchesSelector(e.target, this.props.handle)) ||\n\t\t\t(this.props.cancel && matchesSelector(e.target, this.props.cancel))) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Initiate dragging\n\t\tthis.setState({\n\t\t\tdragging: true,\n\t\t\toffsetX: e.clientX,\n\t\t\toffsetY: e.clientY,\n\t\t\tstartX: parseInt(node.style.left, 10) || 0,\n\t\t\tstartY: parseInt(node.style.top, 10) || 0\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onStart(e, createUIEvent(this));\n\n\t\t// Add event handlers\n\t\taddEvent(window, 'mousemove', this.handleMouseMove);\n\t\taddEvent(window, 'mouseup', this.handleMouseUp);\n\t},\n\n\thandleMouseUp: function (e) {\n\t\t// Short circuit if not currently dragging\n\t\tif (!this.state.dragging) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Turn off dragging\n\t\tthis.setState({\n\t\t\tdragging: false\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onStop(e, createUIEvent(this));\n\n\t\t// Remove event handlers\n\t\tremoveEvent(window, 'mousemove', this.handleMouseMove);\n\t\tremoveEvent(window, 'mouseup', this.handleMouseUp);\n\t},\n\n\thandleMouseMove: function (e) {\n\t\t// Calculate top and left\n\t\tvar clientX = (this.state.startX + (e.clientX - this.state.offsetX));\n\t\tvar clientY = (this.state.startY + (e.clientY - this.state.offsetY));\n\n\t\t// Snap to grid if prop has been provided\n\t\tif (Array.isArray(this.props.grid)) {\n\t\t\tclientX = Math.abs(clientX - this.state.clientX) >= this.props.grid[0]\n\t\t\t\t\t? clientX\n\t\t\t\t\t: this.state.clientX;\n\n\t\t\tclientY = Math.abs(clientY - this.state.clientY) >= this.props.grid[1]\n\t\t\t\t\t? clientY\n\t\t\t\t\t: this.state.clientY;\n\t\t}\n\n\t\t// Update top and left\n\t\tthis.setState({\n\t\t\tclientX: clientX,\n\t\t\tclientY: clientY\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onDrag(e, createUIEvent(this));\n\t},\n\n\trender: function () {\n\t\tvar style = {\n\t\t\t// Set top if vertical drag is enabled\n\t\t\ttop: canDragY(this)\n\t\t\t\t? this.state.clientY\n\t\t\t\t: this.state.startY,\n\n\t\t\t// Set left if horizontal drag is enabled\n\t\t\tleft: canDragX(this)\n\t\t\t\t? this.state.clientX\n\t\t\t\t: this.state.startX\n\t\t};\n\n\t\t// Set zIndex if currently dragging and prop has been provided\n\t\tif (this.state.dragging && !isNaN(this.props.zIndex)) {\n\t\t\tstyle.zIndex = this.props.zIndex;\n\t\t}\n\n\t\t// Reuse the child provided\n\t\t// This makes it flexible to use whatever element is wanted (div, ul, etc)\n\t\treturn React.addons.cloneWithProps(React.Children.only(this.props.children), {\n\t\t\tstyle: style,\n\t\t\tclassName: 'react-draggable',\n\t\t\tonMouseUp: this.handleMouseUp,\n\t\t\tonMouseDown: this.handleMouseDown\n\t\t});\n\t}\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/draggable.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"React\"\n ** module id = 2\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2014 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule emptyFunction\n */\n\nvar copyProperties = require(\"./copyProperties\");\n\nfunction makeEmptyFunction(arg) {\n return function() {\n return arg;\n };\n}\n\n/**\n * This function accepts and discards inputs; it has no side effects. This is\n * primarily useful idiomatically for overridable function endpoints which\n * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n */\nfunction emptyFunction() {}\n\ncopyProperties(emptyFunction, {\n thatReturns: makeEmptyFunction,\n thatReturnsFalse: makeEmptyFunction(false),\n thatReturnsTrue: makeEmptyFunction(true),\n thatReturnsNull: makeEmptyFunction(null),\n thatReturnsThis: function() { return this; },\n thatReturnsArgument: function(arg) { return arg; }\n});\n\nmodule.exports = emptyFunction;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/emptyFunction.js\n ** module id = 3\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2014 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule copyProperties\n */\n\n/**\n * Copy properties from one or more objects (up to 5) into the first object.\n * This is a shallow copy. It mutates the first object and also returns it.\n *\n * NOTE: `arguments` has a very significant performance penalty, which is why\n * we don't support unlimited arguments.\n */\nfunction copyProperties(obj, a, b, c, d, e, f) {\n obj = obj || {};\n\n if (\"production\" !== process.env.NODE_ENV) {\n if (f) {\n throw new Error('Too many arguments passed to copyProperties');\n }\n }\n\n var args = [a, b, c, d, e];\n var ii = 0, v;\n while (args[ii]) {\n v = args[ii++];\n for (var k in v) {\n obj[k] = v[k];\n }\n\n // IE ignores toString in object iteration.. See:\n // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html\n if (v.hasOwnProperty && v.hasOwnProperty('toString') &&\n (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {\n obj.toString = v.toString;\n }\n }\n\n return obj;\n}\n\nmodule.exports = copyProperties;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/copyProperties.js\n ** module id = 4\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\n\nprocess.nextTick = (function () {\n var canSetImmediate = typeof window !== 'undefined'\n && window.setImmediate;\n var canPost = typeof window !== 'undefined'\n && window.postMessage && window.addEventListener\n ;\n\n if (canSetImmediate) {\n return function (f) { return window.setImmediate(f) };\n }\n\n if (canPost) {\n var queue = [];\n window.addEventListener('message', function (ev) {\n var source = ev.source;\n if ((source === window || source === null) && ev.data === 'process-tick') {\n ev.stopPropagation();\n if (queue.length > 0) {\n var fn = queue.shift();\n fn();\n }\n }\n }, true);\n\n return function nextTick(fn) {\n queue.push(fn);\n window.postMessage('process-tick', '*');\n };\n }\n\n return function nextTick(fn) {\n setTimeout(fn, 0);\n };\n})();\n\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n}\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/~/node-libs-browser/~/process/browser.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","webpack:///webpack/bootstrap f7562d32dfb86b76bff9","webpack:///./index.js","webpack:///./lib/draggable.js","webpack:///external \"React\"","webpack:///./~/react/lib/emptyFunction.js","webpack:///./~/react/lib/copyProperties.js","webpack:///(webpack)/~/node-libs-browser/~/process/browser.js"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,O;ACVA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,uBAAe;AACf;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,wC;;;;;;;ACtCA;;;;;;;ACAA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA,+DAA8D,YAAY;AAC1E;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAK;;AAEL;AACA;;AAEA;AACA;AACA,sCAAqC;;AAErC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAC;;AAED;AACA,SAAQ,iBAAiB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,YAAW,QAAQ;AACnB;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA,YAAW,QAAQ;AACnB;AACA;AACA,GAAE;AACF;AACA,GAAE;AACF;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAmC,SAAS;AAC5C;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,cAAc;AACnD,oDAAmD,WAAW;AAC9D;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAqC,IAAI;AACzC;AACA;AACA;AACA;AACA,QAAO;AACP;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAiB;AACjB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,IAAG;;AAEH;AACA;;AAEA;AACA;AACA;AACA,GAAE;;AAEF;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,IAAG;;AAEH;AACA;AACA,GAAE;;AAEF;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,qCAAoC;AACpC;AACA,cAAa;;AAEb;AACA;AACA,IAAG;AACH;AACA,EAAC;;;;;;;ACrcD,gD;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,8CAA6C;AAC7C;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,gCAA+B,aAAa,EAAE;AAC9C,uCAAsC,YAAY;AAClD,EAAC;;AAED;;;;;;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;;;;;;;;ACrDA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,8BAA6B;AAC7B;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAS;;AAET;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,EAAC;;AAED;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA,4BAA2B;AAC3B;AACA;AACA","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"React\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"React\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ReactDraggable\"] = factory(require(\"React\"));\n\telse\n\t\troot[\"ReactDraggable\"] = factory(root[\"React\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_2__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap f7562d32dfb86b76bff9\n **/","module.exports = require('./lib/draggable');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./index.js\n ** module id = 0\n ** module chunks = 0\n **/","'use strict';\n\n/** @jsx React.DOM */\nvar React = require('react/addons');\nvar emptyFunction = require('react/lib/emptyFunction');\n\nfunction createUIEvent(draggable) {\n\treturn {\n\t\tposition: {\n\t\t\ttop: draggable.state.clientY,\n\t\t\tleft: draggable.state.clientX\n\t\t}\n\t};\n}\n\nfunction canDragY(draggable) {\n\treturn draggable.props.axis === 'both' ||\n\t\t\tdraggable.props.axis === 'y';\n}\n\nfunction canDragX(draggable) {\n\treturn draggable.props.axis === 'both' ||\n\t\t\tdraggable.props.axis === 'x';\n}\n\nfunction isFunction(func) {\n return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]'\n}\n\n// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc\nfunction findInArray(array, callback) {\n for (var i = 0, element = array[i], length = array.length; i < length; i++) {\n if (callback.apply(callback, [element, i, array])) return element;\n }\n}\n\nfunction matchesSelector(el, selector) {\n var method = findInArray([\n 'matches',\n 'webkitMatchesSelector',\n 'mozMatchesSelector',\n 'msMatchesSelector',\n 'oMatchesSelector'\n ], function(method){\n return isFunction(el[method]);\n });\n\n return el[method].call(el, selector);\n}\n\n// @credits: http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886\nvar isTouchDevice = 'ontouchstart' in window // works on most browsers\n || 'onmsgesturechange' in window; // works on ie10 on ms surface\n\n// look ::handleDragStart\n//function isMultiTouch(e) {\n// return e.touches && Array.isArray(e.touches) && e.touches.length > 1\n//}\n\n/**\n * simple abstraction for dragging events names\n * */\nvar dragEventFor = (function () {\n var eventsFor = {\n touch: {\n start: 'touchstart',\n move: 'touchmove',\n end: 'touchend'\n },\n mouse: {\n start: 'mousedown',\n move: 'mousemove',\n end: 'mouseup'\n }\n };\n return eventsFor[isTouchDevice ? 'touch' : 'mouse'];\n})();\n\n/**\n * get {clientX, clientY} positions of control\n * */\nfunction getControlPosition(e) {\n var position = !isTouchDevice ? e : e.touches[0];\n return {\n clientX: position.clientX,\n clientY: position.clientY\n }\n}\n\nfunction addEvent(el, event, handler) {\n\tif (!el) { return; }\n\tif (el.attachEvent) {\n\t\tel.attachEvent('on' + event, handler);\n\t} else if (el.addEventListener) {\n\t\tel.addEventListener(event, handler, true);\n\t} else {\n\t\tel['on' + event] = handler;\n\t}\n}\n\nfunction removeEvent(el, event, handler) {\n\tif (!el) { return; }\n\tif (el.detachEvent) {\n\t\tel.detachEvent('on' + event, handler);\n\t} else if (el.removeEventListener) {\n\t\tel.removeEventListener(event, handler, true);\n\t} else {\n\t\tel['on' + event] = null;\n\t}\n}\n\nmodule.exports = React.createClass({\n\tdisplayName: 'Draggable',\n\n\tpropTypes: {\n\t\t/**\n\t\t * `axis` determines which axis the draggable can move.\n\t\t *\n\t\t * 'both' allows movement horizontally and vertically.\n\t\t * 'x' limits movement to horizontal axis.\n\t\t * 'y' limits movement to vertical axis.\n\t\t *\n\t\t * Defaults to 'both'.\n\t\t */\n\t\taxis: React.PropTypes.oneOf(['both', 'x', 'y']),\n\n\t\t/**\n\t\t * `handle` specifies a selector to be used as the handle that initiates drag.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t \treturn (\n\t\t * \t \t \t\n\t\t * \t \t \t
\n\t\t * \t \t \t
Click me to drag
\n\t\t * \t \t \t
This is some other content
\n\t\t * \t \t \t
\n\t\t * \t \t\t
\n\t\t * \t \t);\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\thandle: React.PropTypes.string,\n\n\t\t/**\n\t\t * `cancel` specifies a selector to be used to prevent drag initialization.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return(\n\t\t * \t \n\t\t * \t
\n\t\t * \t \t
You can't drag from here
\n\t\t *\t\t\t\t\t\t
Dragging here works fine
\n\t\t * \t
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tcancel: React.PropTypes.string,\n\n\t\t/**\n\t\t * `grid` specifies the x and y that dragging should snap to.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I snap to a 25 x 25 grid
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tgrid: React.PropTypes.arrayOf(React.PropTypes.number),\n\n\t\t/**\n\t\t * `start` specifies the x and y that the dragged item should start at\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I start with left: 25px; top: 25px;
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tstart: React.PropTypes.object,\n\n\t\t/**\n\t\t * `zIndex` specifies the zIndex to use while dragging.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```jsx\n\t\t * \tvar App = React.createClass({\n\t\t * \t render: function () {\n\t\t * \t return (\n\t\t * \t \n\t\t * \t
I have a zIndex
\n\t\t * \t
\n\t\t * \t );\n\t\t * \t }\n\t\t * \t});\n\t\t * ```\n\t\t */\n\t\tzIndex: React.PropTypes.number,\n\n\t\t/**\n\t\t * Called when dragging starts.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonStart: React.PropTypes.func,\n\n\t\t/**\n\t\t * Called while dragging.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonDrag: React.PropTypes.func,\n\n\t\t/**\n\t\t * Called when dragging stops.\n\t\t *\n\t\t * Example:\n\t\t *\n\t\t * ```js\n\t\t *\tfunction (event, ui) {}\n\t\t * ```\n\t\t *\n\t\t * `event` is the Event that was triggered.\n\t\t * `ui` is an object:\n\t\t *\n\t\t * ```js\n\t\t *\t{\n\t\t *\t\tposition: {top: 0, left: 0}\n\t\t *\t}\n\t\t * ```\n\t\t */\n\t\tonStop: React.PropTypes.func,\n\n\t\t/**\n\t\t * 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)\n\t\t *\n\t\t */\n\t\tonMouseDown: React.PropTypes.func\n\t},\n\n\tcomponentWillUnmount: function() {\n\t\t// Remove any leftover event handlers\n\t\tremoveEvent(window, dragEventFor['move'], this.handleDrag);\n\t\tremoveEvent(window, dragEventFor['end'], this.handleDragEnd);\n\t},\n\n\tgetDefaultProps: function () {\n\t\treturn {\n\t\t\taxis: 'both',\n\t\t\thandle: null,\n\t\t\tcancel: null,\n\t\t\tgrid: null,\n\t\t\tstart: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0\n\t\t\t},\n\t\t\tzIndex: NaN,\n\t\t\tonStart: emptyFunction,\n\t\t\tonDrag: emptyFunction,\n\t\t\tonStop: emptyFunction,\n\t\t\tonMouseDown: emptyFunction\n\t\t};\n\t},\n\n\tgetInitialState: function () {\n\t\treturn {\n\t\t\t// Whether or not currently dragging\n\t\t\tdragging: false,\n\n\t\t\t// Start top/left of this.getDOMNode()\n\t\t\tstartX: 0, startY: 0,\n\n\t\t\t// Offset between start top/left and mouse top/left\n\t\t\toffsetX: 0, offsetY: 0,\n\n\t\t\t// Current top/left of this.getDOMNode()\n\t\t\tclientX: this.props.start.x, clientY: this.props.start.y\n\t\t};\n\t},\n\n\thandleDragStart: function (e) {\n // todo: write right implementation to prevent multitouch drag\n // prevent multi-touch events\n // if (isMultiTouch(e)) {\n // this.handleDragEnd.apply(e, arguments);\n // return\n // }\n\n\t\t// Make it possible to attach event handlers on top of this one\n\t\tthis.props.onMouseDown(e);\n\n\t\tvar node = this.getDOMNode();\n\n\t\t// Short circuit if handle or cancel prop was provided and selector doesn't match\n\t\tif ((this.props.handle && !matchesSelector(e.target, this.props.handle)) ||\n\t\t\t(this.props.cancel && matchesSelector(e.target, this.props.cancel))) {\n\t\t\treturn;\n\t\t}\n\n var dragPoint = getControlPosition(e);\n\n\t\t// Initiate dragging\n\t\tthis.setState({\n\t\t\tdragging: true,\n\t\t\toffsetX: dragPoint.clientX,\n\t\t\toffsetY: dragPoint.clientY,\n\t\t\tstartX: parseInt(node.style.left, 10) || 0,\n\t\t\tstartY: parseInt(node.style.top, 10) || 0\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onStart(e, createUIEvent(this));\n\n\t\t// Add event handlers\n\t\taddEvent(window, dragEventFor['move'], this.handleDrag);\n\t\taddEvent(window, dragEventFor['end'], this.handleDragEnd);\n\t},\n\n\thandleDragEnd: function (e) {\n\t\t// Short circuit if not currently dragging\n\t\tif (!this.state.dragging) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Turn off dragging\n\t\tthis.setState({\n\t\t\tdragging: false\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onStop(e, createUIEvent(this));\n\n\t\t// Remove event handlers\n removeEvent(window, dragEventFor['move'], this.handleDrag);\n removeEvent(window, dragEventFor['end'], this.handleDragEnd);\n\t},\n\n\thandleDrag: function (e) {\n var dragPoint = getControlPosition(e);\n\n\t\t// Calculate top and left\n var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX));\n var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY));\n\n\t\t// Snap to grid if prop has been provided\n\t\tif (Array.isArray(this.props.grid)) {\n\t\t\tclientX = Math.abs(clientX - this.state.clientX) >= this.props.grid[0]\n\t\t\t\t\t? clientX\n\t\t\t\t\t: this.state.clientX;\n\n\t\t\tclientY = Math.abs(clientY - this.state.clientY) >= this.props.grid[1]\n\t\t\t\t\t? clientY\n\t\t\t\t\t: this.state.clientY;\n\t\t}\n\n\t\t// Update top and left\n\t\tthis.setState({\n\t\t\tclientX: clientX,\n\t\t\tclientY: clientY\n\t\t});\n\n\t\t// Call event handler\n\t\tthis.props.onDrag(e, createUIEvent(this));\n\t},\n\n\trender: function () {\n\t\tvar style = {\n\t\t\t// Set top if vertical drag is enabled\n\t\t\ttop: canDragY(this)\n\t\t\t\t? this.state.clientY\n\t\t\t\t: this.state.startY,\n\n\t\t\t// Set left if horizontal drag is enabled\n\t\t\tleft: canDragX(this)\n\t\t\t\t? this.state.clientX\n\t\t\t\t: this.state.startX\n\t\t};\n\n\t\t// Set zIndex if currently dragging and prop has been provided\n\t\tif (this.state.dragging && !isNaN(this.props.zIndex)) {\n\t\t\tstyle.zIndex = this.props.zIndex;\n\t\t}\n\n\t\t// Reuse the child provided\n\t\t// This makes it flexible to use whatever element is wanted (div, ul, etc)\n\t\treturn React.addons.cloneWithProps(React.Children.only(this.props.children), {\n\t\t\tstyle: style,\n\t\t\tclassName: 'react-draggable',\n\n\t\t\tonMouseDown: this.handleDragStart,\n\t\t\tonTouchStart: function(ev){\n ev.preventDefault(); // prevent for scroll\n return this.handleDragStart.apply(this, arguments);\n }.bind(this),\n\n\t\t\tonMouseUp: this.handleDragEnd,\n\t\t\tonTouchEnd: this.handleDragEnd\n\t\t});\n\t}\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./lib/draggable.js\n ** module id = 1\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_2__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"React\"\n ** module id = 2\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2014 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule emptyFunction\n */\n\nvar copyProperties = require(\"./copyProperties\");\n\nfunction makeEmptyFunction(arg) {\n return function() {\n return arg;\n };\n}\n\n/**\n * This function accepts and discards inputs; it has no side effects. This is\n * primarily useful idiomatically for overridable function endpoints which\n * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n */\nfunction emptyFunction() {}\n\ncopyProperties(emptyFunction, {\n thatReturns: makeEmptyFunction,\n thatReturnsFalse: makeEmptyFunction(false),\n thatReturnsTrue: makeEmptyFunction(true),\n thatReturnsNull: makeEmptyFunction(null),\n thatReturnsThis: function() { return this; },\n thatReturnsArgument: function(arg) { return arg; }\n});\n\nmodule.exports = emptyFunction;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/emptyFunction.js\n ** module id = 3\n ** module chunks = 0\n **/","/**\n * Copyright 2013-2014 Facebook, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * @providesModule copyProperties\n */\n\n/**\n * Copy properties from one or more objects (up to 5) into the first object.\n * This is a shallow copy. It mutates the first object and also returns it.\n *\n * NOTE: `arguments` has a very significant performance penalty, which is why\n * we don't support unlimited arguments.\n */\nfunction copyProperties(obj, a, b, c, d, e, f) {\n obj = obj || {};\n\n if (\"production\" !== process.env.NODE_ENV) {\n if (f) {\n throw new Error('Too many arguments passed to copyProperties');\n }\n }\n\n var args = [a, b, c, d, e];\n var ii = 0, v;\n while (args[ii]) {\n v = args[ii++];\n for (var k in v) {\n obj[k] = v[k];\n }\n\n // IE ignores toString in object iteration.. See:\n // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html\n if (v.hasOwnProperty && v.hasOwnProperty('toString') &&\n (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {\n obj.toString = v.toString;\n }\n }\n\n return obj;\n}\n\nmodule.exports = copyProperties;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/react/lib/copyProperties.js\n ** module id = 4\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\n\nprocess.nextTick = (function () {\n var canSetImmediate = typeof window !== 'undefined'\n && window.setImmediate;\n var canPost = typeof window !== 'undefined'\n && window.postMessage && window.addEventListener\n ;\n\n if (canSetImmediate) {\n return function (f) { return window.setImmediate(f) };\n }\n\n if (canPost) {\n var queue = [];\n window.addEventListener('message', function (ev) {\n var source = ev.source;\n if ((source === window || source === null) && ev.data === 'process-tick') {\n ev.stopPropagation();\n if (queue.length > 0) {\n var fn = queue.shift();\n fn();\n }\n }\n }, true);\n\n return function nextTick(fn) {\n queue.push(fn);\n window.postMessage('process-tick', '*');\n };\n }\n\n return function nextTick(fn) {\n setTimeout(fn, 0);\n };\n})();\n\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n}\n\n// TODO(shtylman)\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** (webpack)/~/node-libs-browser/~/process/browser.js\n ** module id = 5\n ** module chunks = 0\n **/"],"sourceRoot":"","file":"./dist/react-draggable.js"} \ No newline at end of file diff --git a/dist/react-draggable.min.js b/dist/react-draggable.min.js index a92984af..aca45e3d 100644 --- a/dist/react-draggable.min.js +++ b/dist/react-draggable.min.js @@ -1,2 +1,2 @@ -!function(root,factory){"object"==typeof exports&&"object"==typeof module?module.exports=factory(require("React")):"function"==typeof define&&define.amd?define(["React"],factory):"object"==typeof exports?exports.ReactDraggable=factory(require("React")):root.ReactDraggable=factory(root.React)}(this,function(__WEBPACK_EXTERNAL_MODULE_2__){return function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){module.exports=__webpack_require__(1)},function(module,exports,__webpack_require__){"use strict";function createUIEvent(draggable){return{position:{top:draggable.state.clientY,left:draggable.state.clientX}}}function canDragY(draggable){return"both"===draggable.props.axis||"y"===draggable.props.axis}function canDragX(draggable){return"both"===draggable.props.axis||"x"===draggable.props.axis}function isFunction(fn){return"function"==typeof fn}function matchesSelector(el,selector){return isFunction(el.matches)?el.matches(selector):isFunction(el.webkitMatchesSelector)?el.webkitMatchesSelector(selector):isFunction(el.mozMatchesSelector)?el.mozMatchesSelector(selector):isFunction(el.msMatchesSelector)?el.msMatchesSelector(selector):isFunction(el.oMatchesSelector)?el.oMatchesSelector(selector):isFunction(el.webkitMatchesSelector)?el.webkitMatchesSelector(selector):void 0}function addEvent(el,event,handler){el&&(el.attachEvent?el.attachEvent("on"+event,handler):el.addEventListener?el.addEventListener(event,handler,!0):el["on"+event]=handler)}function removeEvent(el,event,handler){el&&(el.detachEvent?el.detachEvent("on"+event,handler):el.removeEventListener?el.removeEventListener(event,handler,!0):el["on"+event]=null)}var React=__webpack_require__(2),emptyFunction=__webpack_require__(3);module.exports=React.createClass({displayName:"Draggable",propTypes:{axis:React.PropTypes.oneOf(["both","x","y"]),handle:React.PropTypes.string,cancel:React.PropTypes.string,grid:React.PropTypes.arrayOf(React.PropTypes.number),start:React.PropTypes.object,zIndex:React.PropTypes.number,onStart:React.PropTypes.func,onDrag:React.PropTypes.func,onStop:React.PropTypes.func,onMouseDown:React.PropTypes.func},componentWillUnmount:function(){removeEvent(window,"mousemove",this.handleMouseMove),removeEvent(window,"mouseup",this.handleMouseUp)},getDefaultProps:function(){return{axis:"both",handle:null,cancel:null,grid:null,start:{x:0,y:0},zIndex:0/0,onStart:emptyFunction,onDrag:emptyFunction,onStop:emptyFunction,onMouseDown:emptyFunction}},getInitialState:function(){return{dragging:!1,startX:0,startY:0,offsetX:0,offsetY:0,clientX:this.props.start.x,clientY:this.props.start.y}},handleMouseDown:function(e){this.props.onMouseDown(e);var node=this.getDOMNode();this.props.handle&&!matchesSelector(e.target,this.props.handle)||this.props.cancel&&matchesSelector(e.target,this.props.cancel)||(this.setState({dragging:!0,offsetX:e.clientX,offsetY:e.clientY,startX:parseInt(node.style.left,10)||0,startY:parseInt(node.style.top,10)||0}),this.props.onStart(e,createUIEvent(this)),addEvent(window,"mousemove",this.handleMouseMove),addEvent(window,"mouseup",this.handleMouseUp))},handleMouseUp:function(e){this.state.dragging&&(this.setState({dragging:!1}),this.props.onStop(e,createUIEvent(this)),removeEvent(window,"mousemove",this.handleMouseMove),removeEvent(window,"mouseup",this.handleMouseUp))},handleMouseMove:function(e){var clientX=this.state.startX+(e.clientX-this.state.offsetX),clientY=this.state.startY+(e.clientY-this.state.offsetY);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),this.setState({clientX:clientX,clientY:clientY}),this.props.onDrag(e,createUIEvent(this))},render:function(){var style={top:canDragY(this)?this.state.clientY:this.state.startY,left:canDragX(this)?this.state.clientX:this.state.startX};return this.state.dragging&&!isNaN(this.props.zIndex)&&(style.zIndex=this.props.zIndex),React.addons.cloneWithProps(React.Children.only(this.props.children),{style:style,className:"react-draggable",onMouseUp:this.handleMouseUp,onMouseDown:this.handleMouseDown})}})},function(module){module.exports=__WEBPACK_EXTERNAL_MODULE_2__},function(module,exports,__webpack_require__){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}var copyProperties=__webpack_require__(4);copyProperties(emptyFunction,{thatReturns:makeEmptyFunction,thatReturnsFalse:makeEmptyFunction(!1),thatReturnsTrue:makeEmptyFunction(!0),thatReturnsNull:makeEmptyFunction(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(arg){return arg}}),module.exports=emptyFunction},function(module,exports,__webpack_require__){(function(process){function copyProperties(obj,a,b,c,d,e,f){if(obj=obj||{},"production"!==process.env.NODE_ENV&&f)throw new Error("Too many arguments passed to copyProperties");for(var v,args=[a,b,c,d,e],ii=0;args[ii];){v=args[ii++];for(var k in v)obj[k]=v[k];v.hasOwnProperty&&v.hasOwnProperty("toString")&&"undefined"!=typeof v.toString&&obj.toString!==v.toString&&(obj.toString=v.toString)}return obj}module.exports=copyProperties}).call(exports,__webpack_require__(5))},function(module){function noop(){}var process=module.exports={};process.nextTick=function(){var canSetImmediate="undefined"!=typeof window&&window.setImmediate,canPost="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(canSetImmediate)return function(f){return window.setImmediate(f)};if(canPost){var queue=[];return window.addEventListener("message",function(ev){var source=ev.source;if((source===window||null===source)&&"process-tick"===ev.data&&(ev.stopPropagation(),queue.length>0)){var fn=queue.shift();fn()}},!0),function(fn){queue.push(fn),window.postMessage("process-tick","*")}}return function(fn){setTimeout(fn,0)}}(),process.title="browser",process.browser=!0,process.env={},process.argv=[],process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.binding=function(){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(){throw new Error("process.chdir is not supported")}}])}); +!function(root,factory){"object"==typeof exports&&"object"==typeof module?module.exports=factory(require("React")):"function"==typeof define&&define.amd?define(["React"],factory):"object"==typeof exports?exports.ReactDraggable=factory(require("React")):root.ReactDraggable=factory(root.React)}(this,function(__WEBPACK_EXTERNAL_MODULE_2__){return function(modules){function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:!1};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.loaded=!0,module.exports}var installedModules={};return __webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.p="",__webpack_require__(0)}([function(module,exports,__webpack_require__){module.exports=__webpack_require__(1)},function(module,exports,__webpack_require__){"use strict";function createUIEvent(draggable){return{position:{top:draggable.state.clientY,left:draggable.state.clientX}}}function canDragY(draggable){return"both"===draggable.props.axis||"y"===draggable.props.axis}function canDragX(draggable){return"both"===draggable.props.axis||"x"===draggable.props.axis}function isFunction(func){return"function"==typeof func||"[object Function]"===Object.prototype.toString.call(func)}function findInArray(array,callback){for(var i=0,element=array[i],length=array.length;length>i;i++)if(callback.apply(callback,[element,i,array]))return element}function matchesSelector(el,selector){var method=findInArray(["matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector"],function(method){return isFunction(el[method])});return el[method].call(el,selector)}function getControlPosition(e){var position=isTouchDevice?e.touches[0]:e;return{clientX:position.clientX,clientY:position.clientY}}function addEvent(el,event,handler){el&&(el.attachEvent?el.attachEvent("on"+event,handler):el.addEventListener?el.addEventListener(event,handler,!0):el["on"+event]=handler)}function removeEvent(el,event,handler){el&&(el.detachEvent?el.detachEvent("on"+event,handler):el.removeEventListener?el.removeEventListener(event,handler,!0):el["on"+event]=null)}var React=__webpack_require__(2),emptyFunction=__webpack_require__(3),isTouchDevice="ontouchstart"in window||"onmsgesturechange"in window,dragEventFor=function(){var eventsFor={touch:{start:"touchstart",move:"touchmove",end:"touchend"},mouse:{start:"mousedown",move:"mousemove",end:"mouseup"}};return eventsFor[isTouchDevice?"touch":"mouse"]}();module.exports=React.createClass({displayName:"Draggable",propTypes:{axis:React.PropTypes.oneOf(["both","x","y"]),handle:React.PropTypes.string,cancel:React.PropTypes.string,grid:React.PropTypes.arrayOf(React.PropTypes.number),start:React.PropTypes.object,zIndex:React.PropTypes.number,onStart:React.PropTypes.func,onDrag:React.PropTypes.func,onStop:React.PropTypes.func,onMouseDown:React.PropTypes.func},componentWillUnmount:function(){removeEvent(window,dragEventFor.move,this.handleDrag),removeEvent(window,dragEventFor.end,this.handleDragEnd)},getDefaultProps:function(){return{axis:"both",handle:null,cancel:null,grid:null,start:{x:0,y:0},zIndex:0/0,onStart:emptyFunction,onDrag:emptyFunction,onStop:emptyFunction,onMouseDown:emptyFunction}},getInitialState:function(){return{dragging:!1,startX:0,startY:0,offsetX:0,offsetY:0,clientX:this.props.start.x,clientY:this.props.start.y}},handleDragStart:function(e){this.props.onMouseDown(e);var node=this.getDOMNode();if(!(this.props.handle&&!matchesSelector(e.target,this.props.handle)||this.props.cancel&&matchesSelector(e.target,this.props.cancel))){var dragPoint=getControlPosition(e);this.setState({dragging:!0,offsetX:dragPoint.clientX,offsetY:dragPoint.clientY,startX:parseInt(node.style.left,10)||0,startY:parseInt(node.style.top,10)||0}),this.props.onStart(e,createUIEvent(this)),addEvent(window,dragEventFor.move,this.handleDrag),addEvent(window,dragEventFor.end,this.handleDragEnd)}},handleDragEnd:function(e){this.state.dragging&&(this.setState({dragging:!1}),this.props.onStop(e,createUIEvent(this)),removeEvent(window,dragEventFor.move,this.handleDrag),removeEvent(window,dragEventFor.end,this.handleDragEnd))},handleDrag:function(e){var dragPoint=getControlPosition(e),clientX=this.state.startX+(dragPoint.clientX-this.state.offsetX),clientY=this.state.startY+(dragPoint.clientY-this.state.offsetY);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),this.setState({clientX:clientX,clientY:clientY}),this.props.onDrag(e,createUIEvent(this))},render:function(){var style={top:canDragY(this)?this.state.clientY:this.state.startY,left:canDragX(this)?this.state.clientX:this.state.startX};return this.state.dragging&&!isNaN(this.props.zIndex)&&(style.zIndex=this.props.zIndex),React.addons.cloneWithProps(React.Children.only(this.props.children),{style:style,className:"react-draggable",onMouseDown:this.handleDragStart,onTouchStart:function(ev){return ev.preventDefault(),this.handleDragStart.apply(this,arguments)}.bind(this),onMouseUp:this.handleDragEnd,onTouchEnd:this.handleDragEnd})}})},function(module){module.exports=__WEBPACK_EXTERNAL_MODULE_2__},function(module,exports,__webpack_require__){function makeEmptyFunction(arg){return function(){return arg}}function emptyFunction(){}var copyProperties=__webpack_require__(4);copyProperties(emptyFunction,{thatReturns:makeEmptyFunction,thatReturnsFalse:makeEmptyFunction(!1),thatReturnsTrue:makeEmptyFunction(!0),thatReturnsNull:makeEmptyFunction(null),thatReturnsThis:function(){return this},thatReturnsArgument:function(arg){return arg}}),module.exports=emptyFunction},function(module,exports,__webpack_require__){(function(process){function copyProperties(obj,a,b,c,d,e,f){if(obj=obj||{},"production"!==process.env.NODE_ENV&&f)throw new Error("Too many arguments passed to copyProperties");for(var v,args=[a,b,c,d,e],ii=0;args[ii];){v=args[ii++];for(var k in v)obj[k]=v[k];v.hasOwnProperty&&v.hasOwnProperty("toString")&&"undefined"!=typeof v.toString&&obj.toString!==v.toString&&(obj.toString=v.toString)}return obj}module.exports=copyProperties}).call(exports,__webpack_require__(5))},function(module){function noop(){}var process=module.exports={};process.nextTick=function(){var canSetImmediate="undefined"!=typeof window&&window.setImmediate,canPost="undefined"!=typeof window&&window.postMessage&&window.addEventListener;if(canSetImmediate)return function(f){return window.setImmediate(f)};if(canPost){var queue=[];return window.addEventListener("message",function(ev){var source=ev.source;if((source===window||null===source)&&"process-tick"===ev.data&&(ev.stopPropagation(),queue.length>0)){var fn=queue.shift();fn()}},!0),function(fn){queue.push(fn),window.postMessage("process-tick","*")}}return function(fn){setTimeout(fn,0)}}(),process.title="browser",process.browser=!0,process.env={},process.argv=[],process.on=noop,process.addListener=noop,process.once=noop,process.off=noop,process.removeListener=noop,process.removeAllListeners=noop,process.emit=noop,process.binding=function(){throw new Error("process.binding is not supported")},process.cwd=function(){return"/"},process.chdir=function(){throw new Error("process.chdir is not supported")}}])}); //# sourceMappingURL=react-draggable.min.map \ No newline at end of file diff --git a/dist/react-draggable.min.map b/dist/react-draggable.min.map index c9ce00e4..9f528cd1 100644 --- a/dist/react-draggable.min.map +++ b/dist/react-draggable.min.map @@ -1 +1 @@ -{"version":3,"file":"dist/react-draggable.min.js","sources":["dist/react-draggable.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_2__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","createUIEvent","draggable","position","top","state","clientY","left","clientX","canDragY","props","axis","canDragX","isFunction","fn","matchesSelector","el","selector","matches","webkitMatchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","addEvent","event","handler","attachEvent","addEventListener","removeEvent","detachEvent","removeEventListener","React","emptyFunction","createClass","displayName","propTypes","PropTypes","oneOf","handle","string","cancel","grid","arrayOf","number","start","object","zIndex","onStart","func","onDrag","onStop","onMouseDown","componentWillUnmount","window","handleMouseMove","handleMouseUp","getDefaultProps","x","y","NaN","getInitialState","dragging","startX","startY","offsetX","offsetY","handleMouseDown","e","node","getDOMNode","target","setState","parseInt","style","Array","isArray","Math","abs","render","isNaN","addons","cloneWithProps","Children","only","children","className","onMouseUp","makeEmptyFunction","arg","copyProperties","thatReturns","thatReturnsFalse","thatReturnsTrue","thatReturnsNull","thatReturnsThis","thatReturnsArgument","process","obj","a","b","d","f","env","NODE_ENV","Error","v","args","ii","k","hasOwnProperty","toString","noop","nextTick","canSetImmediate","setImmediate","canPost","postMessage","queue","ev","source","data","stopPropagation","length","shift","push","setTimeout","title","browser","argv","on","addListener","once","off","removeListener","removeAllListeners","emit","binding","cwd","chdir"],"mappings":"CAAA,SAA2CA,KAAMC,SAC1B,gBAAZC,UAA0C,gBAAXC,QACxCA,OAAOD,QAAUD,QAAQG,QAAQ,UACR,kBAAXC,SAAyBA,OAAOC,IAC9CD,QAAQ,SAAUJ,SACQ,gBAAZC,SACdA,QAAwB,eAAID,QAAQG,QAAQ,UAE5CJ,KAAqB,eAAIC,QAAQD,KAAY,QAC5CO,KAAM,SAASC,+BAClB,MAAgB,UAAUC,SAKhB,QAASC,qBAAoBC,UAG5B,GAAGC,iBAAiBD,UACnB,MAAOC,kBAAiBD,UAAUT,OAGnC,IAAIC,QAASS,iBAAiBD,WAC7BT,WACAW,GAAIF,SACJG,QAAQ,EAUT,OANAL,SAAQE,UAAUI,KAAKZ,OAAOD,QAASC,OAAQA,OAAOD,QAASQ,qBAG/DP,OAAOW,QAAS,EAGTX,OAAOD,QAvBf,GAAIU,oBAqCJ,OATAF,qBAAoBM,EAAIP,QAGxBC,oBAAoBO,EAAIL,iBAGxBF,oBAAoBQ,EAAI,GAGjBR,oBAAoB,KAK/B,SAASP,OAAQD,QAASQ,qBAE/BP,OAAOD,QAAUQ,oBAAoB,IAKhC,SAASP,OAAQD,QAASQ,qBAE/B,YAMA,SAASS,eAAcC,WACtB,OACCC,UACCC,IAAKF,UAAUG,MAAMC,QACrBC,KAAML,UAAUG,MAAMG,UAKzB,QAASC,UAASP,WACjB,MAAgC,SAAzBA,UAAUQ,MAAMC,MACI,MAAzBT,UAAUQ,MAAMC,KAGnB,QAASC,UAASV,WACjB,MAAgC,SAAzBA,UAAUQ,MAAMC,MACI,MAAzBT,UAAUQ,MAAMC,KAGnB,QAASE,YAAWC,IACnB,MAAqB,kBAAPA,IAGf,QAASC,iBAAgBC,GAAIC,UAC5B,MAAIJ,YAAWG,GAAGE,SACVF,GAAGE,QAAQD,UACRJ,WAAWG,GAAGG,uBACjBH,GAAGG,sBAAsBF,UACtBJ,WAAWG,GAAGI,oBACjBJ,GAAGI,mBAAmBH,UACnBJ,WAAWG,GAAGK,mBACjBL,GAAGK,kBAAkBJ,UAClBJ,WAAWG,GAAGM,kBACjBN,GAAGM,iBAAiBL,UACjBJ,WAAWG,GAAGG,uBACjBH,GAAGG,sBAAsBF,UAD1B,OAKR,QAASM,UAASP,GAAIQ,MAAOC,SACvBT,KACDA,GAAGU,YACNV,GAAGU,YAAY,KAAOF,MAAOC,SACnBT,GAAGW,iBACbX,GAAGW,iBAAiBH,MAAOC,SAAS,GAEpCT,GAAG,KAAOQ,OAASC,SAIrB,QAASG,aAAYZ,GAAIQ,MAAOC,SAC1BT,KACDA,GAAGa,YACNb,GAAGa,YAAY,KAAOL,MAAOC,SACnBT,GAAGc,oBACbd,GAAGc,oBAAoBN,MAAOC,SAAS,GAEvCT,GAAG,KAAOQ,OAAS,MA5DrB,GAAIO,OAAQvC,oBAAoB,GAC5BwC,cAAgBxC,oBAAoB,EA+DxCP,QAAOD,QAAU+C,MAAME,aACtBC,YAAa,YAEbC,WAUCxB,KAAMoB,MAAMK,UAAUC,OAAO,OAAQ,IAAK,MAsB1CC,OAAQP,MAAMK,UAAUG,OAsBxBC,OAAQT,MAAMK,UAAUG,OAmBxBE,KAAMV,MAAMK,UAAUM,QAAQX,MAAMK,UAAUO,QAmB9CC,MAAOb,MAAMK,UAAUS,OAmBvBC,OAAQf,MAAMK,UAAUO,OAoBxBI,QAAShB,MAAMK,UAAUY,KAoBzBC,OAAQlB,MAAMK,UAAUY,KAoBxBE,OAAQnB,MAAMK,UAAUY,KAMxBG,YAAapB,MAAMK,UAAUY,MAG9BI,qBAAsB,WAErBxB,YAAYyB,OAAQ,YAAahE,KAAKiE,iBACtC1B,YAAYyB,OAAQ,UAAWhE,KAAKkE,gBAGrCC,gBAAiB,WAChB,OACC7C,KAAM,OACN2B,OAAQ,KACRE,OAAQ,KACRC,KAAM,KACNG,OACCa,EAAG,EACHC,EAAG,GAEJZ,OAAQa,IACRZ,QAASf,cACTiB,OAAQjB,cACRkB,OAAQlB,cACRmB,YAAanB,gBAIf4B,gBAAiB,WAChB,OAECC,UAAU,EAGVC,OAAQ,EAAGC,OAAQ,EAGnBC,QAAS,EAAGC,QAAS,EAGrBzD,QAASnB,KAAKqB,MAAMkC,MAAMa,EAAGnD,QAASjB,KAAKqB,MAAMkC,MAAMc,IAIzDQ,gBAAiB,SAAUC,GAE1B9E,KAAKqB,MAAMyC,YAAYgB,EAEvB,IAAIC,MAAO/E,KAAKgF,YAGXhF,MAAKqB,MAAM4B,SAAWvB,gBAAgBoD,EAAEG,OAAQjF,KAAKqB,MAAM4B,SAC9DjD,KAAKqB,MAAM8B,QAAUzB,gBAAgBoD,EAAEG,OAAQjF,KAAKqB,MAAM8B,UAK5DnD,KAAKkF,UACJV,UAAU,EACVG,QAASG,EAAE3D,QACXyD,QAASE,EAAE7D,QACXwD,OAAQU,SAASJ,KAAKK,MAAMlE,KAAM,KAAO,EACzCwD,OAAQS,SAASJ,KAAKK,MAAMrE,IAAK,KAAO,IAIzCf,KAAKqB,MAAMqC,QAAQoB,EAAGlE,cAAcZ,OAGpCkC,SAAS8B,OAAQ,YAAahE,KAAKiE,iBACnC/B,SAAS8B,OAAQ,UAAWhE,KAAKkE,iBAGlCA,cAAe,SAAUY,GAEnB9E,KAAKgB,MAAMwD,WAKhBxE,KAAKkF,UACJV,UAAU,IAIXxE,KAAKqB,MAAMwC,OAAOiB,EAAGlE,cAAcZ,OAGnCuC,YAAYyB,OAAQ,YAAahE,KAAKiE,iBACtC1B,YAAYyB,OAAQ,UAAWhE,KAAKkE,iBAGrCD,gBAAiB,SAAUa,GAE1B,GAAI3D,SAAWnB,KAAKgB,MAAMyD,QAAUK,EAAE3D,QAAUnB,KAAKgB,MAAM2D,SACvD1D,QAAWjB,KAAKgB,MAAM0D,QAAUI,EAAE7D,QAAUjB,KAAKgB,MAAM4D,QAGvDS,OAAMC,QAAQtF,KAAKqB,MAAM+B,QAC5BjC,QAAUoE,KAAKC,IAAIrE,QAAUnB,KAAKgB,MAAMG,UAAYnB,KAAKqB,MAAM+B,KAAK,GAChEjC,QACAnB,KAAKgB,MAAMG,QAEfF,QAAUsE,KAAKC,IAAIvE,QAAUjB,KAAKgB,MAAMC,UAAYjB,KAAKqB,MAAM+B,KAAK,GAChEnC,QACAjB,KAAKgB,MAAMC,SAIhBjB,KAAKkF,UACJ/D,QAASA,QACTF,QAASA,UAIVjB,KAAKqB,MAAMuC,OAAOkB,EAAGlE,cAAcZ,QAGpCyF,OAAQ,WACP,GAAIL,QAEHrE,IAAKK,SAASpB,MACXA,KAAKgB,MAAMC,QACXjB,KAAKgB,MAAM0D,OAGdxD,KAAMK,SAASvB,MACZA,KAAKgB,MAAMG,QACXnB,KAAKgB,MAAMyD,OAUf,OANIzE,MAAKgB,MAAMwD,WAAakB,MAAM1F,KAAKqB,MAAMoC,UAC5C2B,MAAM3B,OAASzD,KAAKqB,MAAMoC,QAKpBf,MAAMiD,OAAOC,eAAelD,MAAMmD,SAASC,KAAK9F,KAAKqB,MAAM0E,WACjEX,MAAOA,MACPY,UAAW,kBACXC,UAAWjG,KAAKkE,cAChBJ,YAAa9D,KAAK6E,sBAQhB,SAASjF,QAEdA,OAAOD,QAAUM,+BAIZ,SAASL,OAAQD,QAASQ,qBAsB/B,QAAS+F,mBAAkBC,KACzB,MAAO,YACL,MAAOA,MASX,QAASxD,kBAbT,GAAIyD,gBAAiBjG,oBAAoB,EAezCiG,gBAAezD,eACb0D,YAAaH,kBACbI,iBAAkBJ,mBAAkB,GACpCK,gBAAiBL,mBAAkB,GACnCM,gBAAiBN,kBAAkB,MACnCO,gBAAiB,WAAa,MAAOzG,OACrC0G,oBAAqB,SAASP,KAAO,MAAOA,QAG9CvG,OAAOD,QAAUgD,eAKZ,SAAS/C,OAAQD,QAASQ,sBAEH,SAASwG,SAyBrC,QAASP,gBAAeQ,IAAKC,EAAGC,EAAGpG,EAAGqG,EAAGjC,EAAGkC,GAG1C,GAFAJ,IAAMA,QAEF,eAAiBD,QAAQM,IAAIC,UAC3BF,EACF,KAAM,IAAIG,OAAM,8CAMpB,KAFA,GACYC,GADRC,MAAQR,EAAGC,EAAGpG,EAAGqG,EAAGjC,GACpBwC,GAAK,EACFD,KAAKC,KAAK,CACfF,EAAIC,KAAKC,KACT,KAAK,GAAIC,KAAKH,GACZR,IAAIW,GAAKH,EAAEG,EAKTH,GAAEI,gBAAkBJ,EAAEI,eAAe,aACf,mBAAdJ,GAAEK,UAA6Bb,IAAIa,WAAaL,EAAEK,WAC5Db,IAAIa,SAAWL,EAAEK,UAIrB,MAAOb,KAGThH,OAAOD,QAAUyG,iBAEY5F,KAAKb,QAASQ,oBAAoB,KAI1D,SAASP,QA8Cd,QAAS8H,SA1CT,GAAIf,SAAU/G,OAAOD,UAErBgH,SAAQgB,SAAW,WACf,GAAIC,iBAAoC,mBAAX5D,SAC1BA,OAAO6D,aACNC,QAA4B,mBAAX9D,SAClBA,OAAO+D,aAAe/D,OAAO1B,gBAGhC,IAAIsF,gBACA,MAAO,UAAUZ,GAAK,MAAOhD,QAAO6D,aAAab,GAGrD,IAAIc,QAAS,CACT,GAAIE,SAYJ,OAXAhE,QAAO1B,iBAAiB,UAAW,SAAU2F,IACzC,GAAIC,QAASD,GAAGC,MAChB,KAAKA,SAAWlE,QAAqB,OAAXkE,SAAgC,iBAAZD,GAAGE,OAC7CF,GAAGG,kBACCJ,MAAMK,OAAS,GAAG,CAClB,GAAI5G,IAAKuG,MAAMM,OACf7G,SAGT,GAEI,SAAkBA,IACrBuG,MAAMO,KAAK9G,IACXuC,OAAO+D,YAAY,eAAgB,MAI3C,MAAO,UAAkBtG,IACrB+G,WAAW/G,GAAI,OAIvBkF,QAAQ8B,MAAQ,UAChB9B,QAAQ+B,SAAU,EAClB/B,QAAQM,OACRN,QAAQgC,QAIRhC,QAAQiC,GAAKlB,KACbf,QAAQkC,YAAcnB,KACtBf,QAAQmC,KAAOpB,KACff,QAAQoC,IAAMrB,KACdf,QAAQqC,eAAiBtB,KACzBf,QAAQsC,mBAAqBvB,KAC7Bf,QAAQuC,KAAOxB,KAEff,QAAQwC,QAAU,WACd,KAAM,IAAIhC,OAAM,qCAIpBR,QAAQyC,IAAM,WAAc,MAAO,KACnCzC,QAAQ0C,MAAQ,WACZ,KAAM,IAAIlC,OAAM"} \ No newline at end of file +{"version":3,"file":"dist/react-draggable.min.js","sources":["dist/react-draggable.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_2__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","createUIEvent","draggable","position","top","state","clientY","left","clientX","canDragY","props","axis","canDragX","isFunction","func","Object","prototype","toString","findInArray","array","callback","i","element","length","apply","matchesSelector","el","selector","method","getControlPosition","e","isTouchDevice","touches","addEvent","event","handler","attachEvent","addEventListener","removeEvent","detachEvent","removeEventListener","React","emptyFunction","window","dragEventFor","eventsFor","touch","start","move","end","mouse","createClass","displayName","propTypes","PropTypes","oneOf","handle","string","cancel","grid","arrayOf","number","object","zIndex","onStart","onDrag","onStop","onMouseDown","componentWillUnmount","handleDrag","handleDragEnd","getDefaultProps","x","y","NaN","getInitialState","dragging","startX","startY","offsetX","offsetY","handleDragStart","node","getDOMNode","target","dragPoint","setState","parseInt","style","Array","isArray","Math","abs","render","isNaN","addons","cloneWithProps","Children","only","children","className","onTouchStart","ev","preventDefault","arguments","bind","onMouseUp","onTouchEnd","makeEmptyFunction","arg","copyProperties","thatReturns","thatReturnsFalse","thatReturnsTrue","thatReturnsNull","thatReturnsThis","thatReturnsArgument","process","obj","a","b","d","f","env","NODE_ENV","Error","v","args","ii","k","hasOwnProperty","noop","nextTick","canSetImmediate","setImmediate","canPost","postMessage","queue","source","data","stopPropagation","fn","shift","push","setTimeout","title","browser","argv","on","addListener","once","off","removeListener","removeAllListeners","emit","binding","cwd","chdir"],"mappings":"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"} \ No newline at end of file diff --git a/lib/draggable.js b/lib/draggable.js index b7928f1a..2585f0f8 100644 --- a/lib/draggable.js +++ b/lib/draggable.js @@ -23,24 +23,68 @@ function canDragX(draggable) { draggable.props.axis === 'x'; } -function isFunction(fn) { - return typeof fn === 'function'; +function isFunction(func) { + return typeof func === 'function' || Object.prototype.toString.call(func) === '[object Function]' +} + +// @credits https://gist.github.com/rogozhnikoff/a43cfed27c41e4e68cdc +function findInArray(array, callback) { + for (var i = 0, element = array[i], length = array.length; i < length; i++) { + if (callback.apply(callback, [element, i, array])) return element; + } } function matchesSelector(el, selector) { - if (isFunction(el.matches)) { - return el.matches(selector); - } else if (isFunction(el.webkitMatchesSelector)) { - return el.webkitMatchesSelector(selector); - } else if (isFunction(el.mozMatchesSelector)) { - return el.mozMatchesSelector(selector); - } else if (isFunction(el.msMatchesSelector)) { - return el.msMatchesSelector(selector); - } else if (isFunction(el.oMatchesSelector)) { - return el.oMatchesSelector(selector); - } else if (isFunction(el.webkitMatchesSelector)) { - return el.webkitMatchesSelector(selector); - } + var method = findInArray([ + 'matches', + 'webkitMatchesSelector', + 'mozMatchesSelector', + 'msMatchesSelector', + 'oMatchesSelector' + ], function(method){ + return isFunction(el[method]); + }); + + return el[method].call(el, selector); +} + +// @credits: http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886 +var isTouchDevice = 'ontouchstart' in window // works on most browsers + || 'onmsgesturechange' in window; // works on ie10 on ms surface + +// look ::handleDragStart +//function isMultiTouch(e) { +// return e.touches && Array.isArray(e.touches) && e.touches.length > 1 +//} + +/** + * simple abstraction for dragging events names + * */ +var dragEventFor = (function () { + var eventsFor = { + touch: { + start: 'touchstart', + move: 'touchmove', + end: 'touchend' + }, + mouse: { + start: 'mousedown', + move: 'mousemove', + end: 'mouseup' + } + }; + return eventsFor[isTouchDevice ? 'touch' : 'mouse']; +})(); + +/** + * get {clientX, clientY} positions of control + * */ +function getControlPosition(e) { + var position = !isTouchDevice ? e : e.touches[0]; + return { + clientX: position.clientX, + clientY: position.clientY + } } function addEvent(el, event, handler) { @@ -250,8 +294,8 @@ module.exports = React.createClass({ componentWillUnmount: function() { // Remove any leftover event handlers - removeEvent(window, 'mousemove', this.handleMouseMove); - removeEvent(window, 'mouseup', this.handleMouseUp); + removeEvent(window, dragEventFor['move'], this.handleDrag); + removeEvent(window, dragEventFor['end'], this.handleDragEnd); }, getDefaultProps: function () { @@ -288,7 +332,14 @@ module.exports = React.createClass({ }; }, - handleMouseDown: function (e) { + handleDragStart: function (e) { + // todo: write right implementation to prevent multitouch drag + // prevent multi-touch events + // if (isMultiTouch(e)) { + // this.handleDragEnd.apply(e, arguments); + // return + // } + // Make it possible to attach event handlers on top of this one this.props.onMouseDown(e); @@ -300,11 +351,13 @@ module.exports = React.createClass({ return; } + var dragPoint = getControlPosition(e); + // Initiate dragging this.setState({ dragging: true, - offsetX: e.clientX, - offsetY: e.clientY, + offsetX: dragPoint.clientX, + offsetY: dragPoint.clientY, startX: parseInt(node.style.left, 10) || 0, startY: parseInt(node.style.top, 10) || 0 }); @@ -313,11 +366,11 @@ module.exports = React.createClass({ this.props.onStart(e, createUIEvent(this)); // Add event handlers - addEvent(window, 'mousemove', this.handleMouseMove); - addEvent(window, 'mouseup', this.handleMouseUp); + addEvent(window, dragEventFor['move'], this.handleDrag); + addEvent(window, dragEventFor['end'], this.handleDragEnd); }, - handleMouseUp: function (e) { + handleDragEnd: function (e) { // Short circuit if not currently dragging if (!this.state.dragging) { return; @@ -332,14 +385,16 @@ module.exports = React.createClass({ this.props.onStop(e, createUIEvent(this)); // Remove event handlers - removeEvent(window, 'mousemove', this.handleMouseMove); - removeEvent(window, 'mouseup', this.handleMouseUp); + removeEvent(window, dragEventFor['move'], this.handleDrag); + removeEvent(window, dragEventFor['end'], this.handleDragEnd); }, - handleMouseMove: function (e) { + handleDrag: function (e) { + var dragPoint = getControlPosition(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)); + var clientX = (this.state.startX + (dragPoint.clientX - this.state.offsetX)); + var clientY = (this.state.startY + (dragPoint.clientY - this.state.offsetY)); // Snap to grid if prop has been provided if (Array.isArray(this.props.grid)) { @@ -385,8 +440,15 @@ module.exports = React.createClass({ return React.addons.cloneWithProps(React.Children.only(this.props.children), { style: style, className: 'react-draggable', - onMouseUp: this.handleMouseUp, - onMouseDown: this.handleMouseDown + + onMouseDown: this.handleDragStart, + onTouchStart: function(ev){ + ev.preventDefault(); // prevent for scroll + return this.handleDragStart.apply(this, arguments); + }.bind(this), + + onMouseUp: this.handleDragEnd, + onTouchEnd: this.handleDragEnd }); } });