You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/10/28 19:01:42 UTC

[20/50] [abbrv] allura git commit: [#7919] Add NavBar dependencies

http://git-wip-us.apache.org/repos/asf/allura/blob/4c96a0cd/Allura/allura/public/nf/js/react-drag.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/react-drag.js b/Allura/allura/public/nf/js/react-drag.js
new file mode 100644
index 0000000..c52ac50
--- /dev/null
+++ b/Allura/allura/public/nf/js/react-drag.js
@@ -0,0 +1,557 @@
+(function (root, factory) {
+    if (typeof define === 'function' && define.amd) {
+        define(['React'], factory);
+    } else if (typeof exports === 'object') {
+        module.exports = factory(require('react/addons'));
+    } else {
+        root.ReactDrag = factory(root.React);
+    }
+}(this, function (React) {
+    /* global React */
+    /* exported ReactDrag */
+    'use strict';
+
+    function classNames() {
+        var classes = '';
+        for (var i = 0; i < arguments.length; i++) {
+            var arg = arguments[i];
+            if (!arg) continue;
+            var argType = typeof arg;
+            if ('string' === argType || 'number' === argType) {
+                classes += ' ' + arg;
+            } else if (Array.isArray(arg)) {
+                classes += ' ' + classNames.apply(null, arg);
+            } else if ('object' === argType) {
+                for (var key in arg) {
+                    if (arg.hasOwnProperty(key) && arg[key]) {
+                        classes += ' ' + key;
+                    }
+                }
+            }
+        }
+        return classes.substr(1);
+    }
+
+    var emptyFunction = function () {
+    };
+    var CX = classNames;
+
+    function createUIEvent(draggable) {
+        return {
+            position: {
+                top: draggable.state.pageY,
+                left: draggable.state.pageX
+            }
+        };
+    }
+
+    function canDragY(draggable) {
+        return draggable.props.axis === 'both' ||
+            draggable.props.axis === 'y';
+    }
+
+    function canDragX(draggable) {
+        return draggable.props.axis === 'both' ||
+            draggable.props.axis === 'x';
+    }
+
+    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, length = array.length, element = null; i < length; i += 1) {
+            element = array[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);
+    }
+
+// @credits:
+// http://stackoverflow.com/questions/4817029/whats-the-best-way-to-detect-a-touch-screen-device-using-javascript/4819886#4819886
+    /* Conditional to fix node server side rendering of component */
+    if (typeof window === 'undefined') {
+        // Do Node Stuff
+        var isTouchDevice = false;
+    } else {
+        // Do Browser Stuff
+        var isTouchDevice = 'ontouchstart' in window // works on most browsers
+            || 'onmsgesturechange' in window; // works on ie10 on ms surface
+        // Check for IE11
+        try {
+            document.createEvent('TouchEvent');
+        } catch (e) {
+            isTouchDevice = false;
+        }
+
+    }
+
+// 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 {pageX, pageY} positions of control
+     * */
+    function getControlPosition(e) {
+        var position = (e.touches && e.touches[0]) || e;
+        return {
+            pageX: position.pageX,
+            pageY: position.pageY
+        };
+    }
+
+    function getBoundPosition(pageX, pageY, bound, target) {
+        if (bound) {
+            if ((typeof bound !== 'string' && bound.toLowerCase() !== 'parent') &&
+                (typeof bound !== 'object')) {
+                console.warn('Bound should either "parent" or an object');
+            }
+            var par = target.parentNode;
+            var topLimit = bound.top || 0;
+            var leftLimit = bound.left || 0;
+            var rightLimit = bound.right || par.offsetWidth;
+            var bottomLimit = bound.bottom || par.offsetHeight;
+            pageX = Math.min(pageX, rightLimit - target.offsetWidth);
+            pageY = Math.min(pageY, bottomLimit - target.offsetHeight);
+            pageX = Math.max(leftLimit, pageX);
+            pageY = Math.max(topLimit, pageY);
+        }
+        return {
+            pageX: pageX,
+            pageY: pageY
+        };
+    }
+
+    function addEvent(el, event, handler) {
+        if (!el) {
+            return;
+        }
+        if (el.attachEvent) {
+            el.attachEvent('on' + event, handler);
+        } else if (el.addEventListener) {
+            el.addEventListener(event, handler, true);
+        } else {
+            el['on' + event] = handler;
+        }
+    }
+
+    function removeEvent(el, event, handler) {
+        if (!el) {
+            return;
+        }
+        if (el.detachEvent) {
+            el.detachEvent('on' + event, handler);
+        } else if (el.removeEventListener) {
+            el.removeEventListener(event, handler, true);
+        } else {
+            el['on' + event] = null;
+        }
+    }
+
+    var ReactDrag = React.createClass({
+        displayName: 'Draggable',
+
+        propTypes: {
+            /**
+             * `axis` determines which axis the draggable can move.
+             *
+             * 'both' allows movement horizontally and vertically.
+             * 'x' limits movement to horizontal axis.
+             * 'y' limits movement to vertical axis.
+             *
+             * Defaults to 'both'.
+             */
+            axis: React.PropTypes.oneOf(['both', 'x', 'y']),
+
+            /**
+             * `handle` specifies a selector to be used as the handle
+             * that initiates drag.
+             *
+             * Example:
+             *
+             * ```jsx
+             *   var App = React.createClass({
+     *       render: function () {
+     *         return (
+     *            <Draggable handle=".handle">
+     *              <div>
+     *                  <div className="handle">Click me to drag</div>
+     *                  <div>This is some other content</div>
+     *              </div>
+     *           </Draggable>
+     *         );
+     *       }
+     *   });
+             * ```
+             */
+            handle: React.PropTypes.string,
+
+            /**
+             * `cancel` specifies a selector to be used to prevent drag initialization.
+             *
+             * Example:
+             *
+             * ```jsx
+             *   var App = React.createClass({
+     *       render: function () {
+     *           return(
+     *               <Draggable cancel=".cancel">
+     *                   <div>
+     *             <div className="cancel">You can't drag from here</div>
+     *            <div>Dragging here works fine</div>
+     *                   </div>
+     *               </Draggable>
+     *           );
+     *       }
+     *   });
+             * ```
+             */
+            cancel: React.PropTypes.string,
+
+            /**
+             * `grid` specifies the x and y that dragging should snap to.
+             *
+             * Example:
+             *
+             * ```jsx
+             *   var App = React.createClass({
+     *       render: function () {
+     *           return (
+     *               <Draggable grid={[25, 25]}>
+     *                   <div>I snap to a 25 x 25 grid</div>
+     *               </Draggable>
+     *           );
+     *       }
+     *   });
+             * ```
+             */
+            grid: React.PropTypes.arrayOf(React.PropTypes.number),
+
+            /**
+             * `start` specifies the x and y that the dragged item should start at
+             *
+             * Example:
+             *
+             * ```jsx
+             *   var App = React.createClass({
+     *       render: function () {
+     *           return (
+     *               <Draggable start={{x: 25, y: 25}}>
+     *                   <div>I start with left: 25px; top: 25px;</div>
+     *               </Draggable>
+     *           );
+     *       }
+     *   });
+             * ```
+             */
+            start: React.PropTypes.object,
+
+            /**
+             * Called when dragging starts.
+             *
+             * Example:
+             *
+             * ```js
+             *  function (event, ui) {}
+             * ```
+             *
+             * `event` is the Event that was triggered.
+             * `ui` is an object:
+             *
+             * ```js
+             *  {
+     *    position: {top: 0, left: 0}
+     *  }
+             * ```
+             */
+            onStart: React.PropTypes.func,
+
+            /**
+             * Called while dragging.
+             *
+             * Example:
+             *
+             * ```js
+             *  function (event, ui) {}
+             * ```
+             *
+             * `event` is the Event that was triggered.
+             * `ui` is an object:
+             *
+             * ```js
+             *  {
+     *    position: {top: 0, left: 0}
+     *  }
+             * ```
+             */
+            onDrag: React.PropTypes.func,
+
+            /**
+             * Called when dragging stops.
+             *
+             * Example:
+             *
+             * ```js
+             *  function (event, ui) {}
+             * ```
+             *
+             * `event` is the Event that was triggered.
+             * `ui` is an object:
+             *
+             * ```js
+             *  {
+     *    position: {top: 0, left: 0}
+     *  }
+             * ```
+             */
+            onStop: React.PropTypes.func,
+
+            /**
+             * A workaround option which can be passed if
+             * onMouseDown needs to be accessed,
+             * since it'll always be blocked (due to that
+             * there's internal use of onMouseDown)
+             *
+             */
+            onMouseDown: React.PropTypes.func,
+
+            /**
+             * Defines the bounderies around the element
+             * could be dragged. This property could be
+             * object or a string. If used as object
+             * the bounderies should be defined as:
+             *
+             * {
+     *   left: LEFT_BOUND,
+     *   right: RIGHT_BOUND,
+     *   top: TOP_BOUND,
+     *   bottom: BOTTOM_BOUND
+     * }
+             *
+             * The only acceptable string
+             * property is: "parent".
+             */
+            bound: React.PropTypes.any
+        },
+
+        componentWillUnmount: function () {
+            // Remove any leftover event handlers
+            removeEvent(window, dragEventFor.move, this.handleDrag);
+            removeEvent(window, dragEventFor.end, this.handleDragEnd);
+        },
+
+        getDefaultProps: function () {
+            return {
+                axis: 'both',
+                handle: null,
+                cancel: null,
+                grid: null,
+                bound: false,
+                start: {
+                    x: 0,
+                    y: 0
+                },
+                onStart: emptyFunction,
+                onDrag: emptyFunction,
+                onStop: emptyFunction,
+                onMouseDown: emptyFunction
+            };
+        },
+
+        getInitialState: function () {
+            return {
+                // Whether or not currently dragging
+                dragging: false,
+
+                // Start top/left of this.getDOMNode()
+                startX: 0,
+                startY: 0,
+
+                // Offset between start top/left and mouse top/left
+                offsetX: 0,
+                offsetY: 0,
+
+                // Current top/left of this.getDOMNode()
+                pageX: this.props.start.x,
+                pageY: this.props.start.y
+            };
+        },
+
+        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);
+
+            var node = this.getDOMNode();
+
+            // Short circuit if handle or cancel prop was provided
+            // and selector doesn't match
+            if ((this.props.handle && !matchesSelector(e.target, this.props.handle)) ||
+                (this.props.cancel && matchesSelector(e.target, this.props.cancel))) {
+                return;
+            }
+
+            var dragPoint = getControlPosition(e);
+
+            // Initiate dragging
+            this.setState({
+                dragging: true,
+                offsetX: parseInt(dragPoint.pageX, 10),
+                offsetY: parseInt(dragPoint.pageY, 10),
+                startX: parseInt(node.style.left, 10) || 0,
+                startY: parseInt(node.style.top, 10) || 0
+            });
+
+            // Call event handler
+            this.props.onStart(e, createUIEvent(this));
+
+            // Add event handlers
+            addEvent(window, dragEventFor.move, this.handleDrag);
+            addEvent(window, dragEventFor.end, this.handleDragEnd);
+        },
+
+        handleDragEnd: function (e) {
+            // Short circuit if not currently dragging
+            if (!this.state.dragging) {
+                return;
+            }
+
+            // Turn off dragging
+            this.setState({
+                dragging: false
+            });
+
+            // Call event handler
+            this.props.onStop(e, createUIEvent(this));
+
+            // Remove event handlers
+            removeEvent(window, dragEventFor.move, this.handleDrag);
+            removeEvent(window, dragEventFor.end, this.handleDragEnd);
+        },
+
+        handleDrag: function (e) {
+            var dragPoint = getControlPosition(e);
+
+            // Calculate top and left
+            var pageX = (this.state.startX +
+            (dragPoint.pageX - this.state.offsetX));
+            var pageY = (this.state.startY +
+            (dragPoint.pageY - this.state.offsetY));
+            var pos =
+                getBoundPosition(pageX, pageY, this.props.bound, this.getDOMNode());
+            pageX = pos.pageX;
+            pageY = pos.pageY;
+
+            // Snap to grid if prop has been provided
+            if (Array.isArray(this.props.grid)) {
+                var directionX = pageX < parseInt(this.state.pageX, 10) ? -1 : 1;
+                var directionY = pageY < parseInt(this.state.pageY, 10) ? -1 : 1;
+
+                pageX = Math.abs(pageX - parseInt(this.state.pageX, 10)) >=
+                this.props.grid[0]
+                    ? (parseInt(this.state.pageX, 10) +
+                (this.props.grid[0] * directionX))
+                    : this.state.pageX;
+
+                pageY = Math.abs(pageY - parseInt(this.state.pageY, 10)) >=
+                this.props.grid[1]
+                    ? (parseInt(this.state.pageY, 10) +
+                (this.props.grid[1] * directionY))
+                    : this.state.pageY;
+            }
+
+            // Update top and left
+            this.setState({
+                pageX: pageX,
+                pageY: pageY
+            });
+
+            // Call event handler
+            this.props.onDrag(e, createUIEvent(this));
+
+            // Prevent the default behavior
+            e.preventDefault();
+        },
+
+        render: function () {
+            var style = {
+                // Set top if vertical drag is enabled
+                top: canDragY(this)
+                    ? this.state.pageY
+                    : this.state.startY,
+
+                // Set left if horizontal drag is enabled
+                left: canDragX(this)
+                    ? this.state.pageX
+                    : this.state.startX
+            };
+
+            var className = CX({
+                'react-drag': true,
+                'react-drag-dragging': this.state.dragging
+            });
+            // Reuse the child provided
+            // This makes it flexible to use whatever element is wanted (div, ul, etc)
+            return React.addons.cloneWithProps(
+                React.Children.only(this.props.children), {
+                    style: style,
+                    className: className,
+
+                    onMouseDown: this.handleDragStart,
+                    onTouchStart: function (ev) {
+                        ev.preventDefault(); // prevent for scroll
+                        return this.handleDragStart.apply(this, arguments);
+                    }.bind(this),
+
+                    onMouseUp: this.handleDragEnd,
+                    onTouchEnd: this.handleDragEnd
+                });
+        }
+    });
+
+    return ReactDrag;
+}));
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/4c96a0cd/Allura/allura/public/nf/js/react-reorderable.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/react-reorderable.js b/Allura/allura/public/nf/js/react-reorderable.js
new file mode 100755
index 0000000..401d6a5
--- /dev/null
+++ b/Allura/allura/public/nf/js/react-reorderable.js
@@ -0,0 +1,316 @@
+(function(root, factory) {
+  if (typeof define === 'function' && define.amd) {
+    define(['React', 'ReactDrag'], factory);
+  } else if (typeof exports === 'object') {
+    module.exports = factory(require('react/addons'), require('react-drag'));
+  } else {
+    root.ReactReorderable = factory(root.React, root.ReactDrag);
+  }
+}(this, function(React, ReactDrag) {
+'use strict';
+
+function getClosestReorderable(el) {
+  while (el) {
+    if (el.className &&
+        el.className.indexOf('react-reorderable-item') >= 0) {
+      return el;
+    }
+    el = el.parentNode;
+  }
+  return null;
+}
+
+var SIBLING_TYPES = {
+  NONE: 0,
+  NEXT: 1,
+  PREVIOUS: 2
+};
+
+function getControlPosition(e) {
+  var position = (e.touches && e.touches[0]) || e;
+  return {
+    clientX: position.clientX,
+    clientY: position.clientY
+  };
+}
+
+function getHorizontalSiblingType(e, node) {
+  var rect = node.getBoundingClientRect();
+  var nodeTop = rect.top;
+  var nodeLeft = rect.left;
+  var width = rect.width;
+  var height = rect.height;
+  var position = getControlPosition(e);
+
+  if (position.clientY < nodeTop || position.clientY > nodeTop + height) {
+    return SIBLING_TYPES.NONE;
+  }
+  if (position.clientX > nodeLeft && position.clientX < nodeLeft + 1 / 2 * width) {
+    return SIBLING_TYPES.NEXT;
+  }
+  if (position.clientX > nodeLeft + 1 / 2 * width && position.clientX < nodeLeft + width) {
+    return SIBLING_TYPES.PREVIOUS;
+  }
+  return SIBLING_TYPES.NONE;
+}
+
+function getVerticalSiblingType(e, node) {
+  var rect = node.getBoundingClientRect();
+  var nodeTop = rect.top;
+  var nodeLeft = rect.left;
+  var width = rect.width;
+  var height = rect.height;
+  var position = getControlPosition(e);
+
+  if (position.clientX < nodeLeft || position.clientX > nodeLeft + width) {
+    return SIBLING_TYPES.NONE;
+  }
+  if (position.clientY > nodeTop && position.clientY < nodeTop + 1 / 2 * height) {
+    return SIBLING_TYPES.NEXT;
+  }
+  if (position.clientY > nodeTop + 1 / 2 * height && position.clientY < nodeTop + height) {
+    return SIBLING_TYPES.PREVIOUS;
+  }
+  return SIBLING_TYPES.NONE;
+}
+
+function getSiblingNode(e, node, mode) {
+  var p = node.parentNode;
+  var siblings = p.children;
+  var current;
+  var done = false;
+  var result = {};
+  mode = mode || 'list';
+  for (var i = 0; i < siblings.length && !done; i += 1) {
+    current = siblings[i];
+    if (current.getAttribute('data-reorderable-key') !==
+        node.getAttribute('data-reorderable-key')) {
+      // The cursor should be around the middle of the item
+      var siblingType;
+      if (mode === 'list') {
+        siblingType = getVerticalSiblingType(e, current);
+      } else {
+        siblingType = getHorizontalSiblingType(e, current);
+      }
+      if (siblingType !== SIBLING_TYPES.NONE) {
+        result.node = current;
+        result.type = siblingType;
+        return result;
+      }
+    }
+  }
+  return result;
+}
+
+function indexChildren(children) {
+  var prefix = 'node-';
+  var map = {};
+  var ids = [];
+  var id;
+  for (var i = 0; i < children.length; i += 1) {
+    var id = prefix + (i + 1);
+    ids.push(id);
+    children[i] = React.createElement("div", {className: "react-reorderable-item", 
+         key: id, "data-reorderable-key": id}, 
+        children[i]
+      );
+    map[id] = children[i];
+  }
+  return { map: map, ids: ids };
+}
+
+function is(elem, selector) {
+  var matches = elem.parentNode.querySelectorAll(selector);
+  for (var i = 0; i < matches.length; i += 1) {
+    if (elem === matches[i]) {
+      return true;
+    }
+  }
+  return false;
+}
+
+function getNodesOrder(current, sibling, order) {
+  var currentKey = current.getAttribute('data-reorderable-key');
+  var currentPos = order.indexOf(currentKey);
+  order.splice(currentPos, 1);
+  var siblingKey = sibling.node.getAttribute('data-reorderable-key');
+  var siblingKeyPos = order.indexOf(siblingKey);
+  if (sibling.type === SIBLING_TYPES.PREVIOUS) {
+    order.splice(siblingKeyPos + 1, 0, currentKey);
+  } else {
+    order.splice(siblingKeyPos, 0, currentKey);
+  }
+  return order;
+}
+
+
+var ReactReorderable = React.createClass({displayName: "ReactReorderable",
+  componentWillMount: function () {
+    window.addEventListener('mouseup', this._mouseupHandler = function () {
+      this.setState({
+        mouseDownPosition: null
+      });
+    }.bind(this));
+  },
+  componentWillUnmount: function () {
+    window.removeEventListener('mouseup', this._mouseupHandler);
+  },
+  componentWillReceiveProps: function (nextProps) {
+    if (nextProps.children) {
+      var res = indexChildren(nextProps.children);
+      this.setState({
+        order: res.ids,
+        reorderableMap: res.map
+      });
+    }
+  },
+  getInitialState: function () {
+    var res = indexChildren(this.props.children);
+    return {
+      order: res.ids,
+      startPosition: null,
+      activeItem: null,
+      reorderableMap: res.map
+    };
+  },
+  onDragStop: function (e) {
+    this.setState({
+      activeItem: null,
+      startPosition: null
+    });
+    this.props.onDrop(this.state.order.map(function (id) {
+      return this.state.reorderableMap[id].props.children;
+    }, this));
+  },
+  onDrag: function (e) {
+    var handle = this.refs.handle.getDOMNode();
+    var sibling = getSiblingNode(e, handle, this.props.mode);
+
+    if (sibling && sibling.node) {
+      var oldOrder = this.state.order.slice();
+      var order = getNodesOrder(getClosestReorderable(handle), sibling, this.state.order);
+      var changed = false;
+      for (var i = 0; i < order.length && !changed; i += 1) {
+        if (order[i] !== oldOrder[i]) {
+          changed = true;
+        }
+      }
+      if (changed) {
+        this.props.onChange(this.state.order.map(function (id) {
+          return this.state.reorderableMap[id].props.children;
+        }, this));
+      }
+      this.setState({
+        order: order
+      });
+    }
+  },
+  onMouseDown: function (e) {
+    var position;
+
+    if (!this.props.handle || is(e.target, this.props.handle)) {
+      position = getControlPosition(e);
+
+      this.setState({
+        mouseDownPosition: {
+          x: position.clientX,
+          y: position.clientY
+        }
+      });
+    }
+  },
+  onTouchStart: function(e) {
+    e.preventDefault(); // prevent scrolling
+    this.onMouseDown(e);
+  },
+  onMouseMove: function (e) {
+    var position;
+
+    if (!this.state.activeItem) {
+      var initial = this.state.mouseDownPosition;
+      // Still not clicked
+      if (!initial) {
+        return;
+      }
+
+      position = getControlPosition(e);
+
+      if (Math.abs(position.clientX - initial.x) >= 5 ||
+          Math.abs(position.clientY - initial.y) >= 5) {
+        var node = getClosestReorderable(e.target);
+        var nativeEvent = e.nativeEvent;
+        var id = node.getAttribute('data-reorderable-key');
+        // React resets the event's properties
+        this.props.onDragStart(this.state.reorderableMap[id]);
+        this.activeItem = node;
+        var parentNode = node.parentNode && node.parentNode.parentNode;
+        this.setState({
+          mouseDownPosition: null,
+          activeItem: id,
+          startPosition: {
+            x: node.offsetLeft - (parentNode && parentNode.scrollLeft || 0),
+            y: node.offsetTop - (parentNode && parentNode.scrollTop || 0)
+          }
+        }, function () {
+          this.refs.handle.handleDragStart(nativeEvent);
+        }.bind(this));
+      }
+    }
+  },
+  render: function () {
+    var children = this.state.order.map(function (id) {
+      var className = (this.state.activeItem) ? 'noselect ' : '';
+      if (this.state.activeItem === id) {
+        className += 'react-reorderable-item-active';
+      }
+      return React.addons.cloneWithProps(
+        this.state.reorderableMap[id], {
+          key: 'reaorderable-' + id,
+          ref: 'active',
+          onMouseDown: this.onMouseDown,
+          onMouseMove: this.onMouseMove,
+          onTouchStart: this.onTouchStart,
+          onTouchMove: this.onMouseMove,
+          className: className
+      });
+    }, this);
+    var handle;
+    if (this.state.activeItem) {
+      var pos = this.state.startPosition;
+      handle = React.addons.cloneWithProps(
+        this.state.reorderableMap[this.state.activeItem], {
+          className: 'react-reorderable-handle'
+      });
+      handle =
+        React.createElement(ReactDrag, {onStop: this.onDragStop, 
+          onDrag: this.onDrag, 
+          ref: "handle", 
+          start: { x: pos.x, y: pos.y}}, 
+          handle
+        );
+    }
+    return (
+      React.createElement("div", {ref: "wrapper"}, 
+        children, 
+        handle
+      )
+    );
+  }
+});
+
+ReactReorderable.propTypes = {
+  onDragStart: React.PropTypes.func,
+  onDrag: React.PropTypes.func,
+  onDrop: React.PropTypes.func,
+  onChange: React.PropTypes.func
+};
+
+ReactReorderable.defaultProps = {
+  onDragStart: function () {},
+  onDrag: function () {},
+  onDrop: function () {},
+  onChange: function () {}
+};
+
+return ReactReorderable;
+}));
\ No newline at end of file