diff --git a/src/FixedDataTable.js b/src/FixedDataTable.js index 38e5ad8c..54ad0b5f 100644 --- a/src/FixedDataTable.js +++ b/src/FixedDataTable.js @@ -773,11 +773,17 @@ var FixedDataTable = React.createClass({ var columnBefore = this.state.columnReorderingData.columnBefore; var columnAfter = this.state.columnReorderingData.columnAfter; var reorderColumn = this.state.columnReorderingData.columnKey; + var cancelReorder = this.state.columnReorderingData.cancelReorder; this.setState({ isColumnReordering: false, columnReorderingData: {} }); + + if (cancelReorder) { + return + } + this.props.onColumnReorderEndCallback({ columnBefore, columnAfter, reorderColumn }); diff --git a/src/FixedDataTableColumnReorderHandle.js b/src/FixedDataTableColumnReorderHandle.js index 1821fede..1c44d2aa 100644 --- a/src/FixedDataTableColumnReorderHandle.js +++ b/src/FixedDataTableColumnReorderHandle.js @@ -110,11 +110,12 @@ var FixedDataTableColumnReorderHandle = React.createClass({ this._distance = this.state.dragDistance + deltaX; }, - _onColumnReorderEnd() { + _onColumnReorderEnd(/*boolean*/ cancelReorder) { this._animating = false; cancelAnimationFrame(this.frameId); this.frameId = null; this._mouseMoveTracker.releaseMouseMoves(); + this.props.columnReorderingData.cancelReorder = cancelReorder; this.props.onColumnReorderEnd(); }, diff --git a/src/vendor_upstream/dom/DOMMouseMoveTracker.js b/src/vendor_upstream/dom/DOMMouseMoveTracker.js index e7eff50d..49f4c00d 100644 --- a/src/vendor_upstream/dom/DOMMouseMoveTracker.js +++ b/src/vendor_upstream/dom/DOMMouseMoveTracker.js @@ -38,6 +38,7 @@ class DOMMouseMoveTracker { this._domNode = domNode; this._onMove = onMove; this._onMoveEnd = onMoveEnd; + this._onMouseEnd = this._onMouseEnd.bind(this); this._onMouseMove = this._onMouseMove.bind(this); this._onMouseUp = this._onMouseUp.bind(this); this._didMouseMove = this._didMouseMove.bind(this); @@ -50,7 +51,7 @@ class DOMMouseMoveTracker { * in order to grab inital state. */ captureMouseMoves(/*object*/ event) { - if (!this._eventMoveToken && !this._eventUpToken) { + if (!this._eventMoveToken && !this._eventUpToken && !this._eventLeaveToken && !this._eventOutToken) { this._eventMoveToken = EventListener.listen( this._domNode, 'mousemove', @@ -61,6 +62,16 @@ class DOMMouseMoveTracker { 'mouseup', this._onMouseUp ); + this._eventLeaveToken = EventListener.listen( + this._domNode, + 'mouseleave', + this._onMouseEnd + ); + this._eventOutToken = EventListener.listen( + this._domNode, + 'mouseout', + this.onMouseEnd + ); } if (!this._isDragging) { @@ -77,11 +88,15 @@ class DOMMouseMoveTracker { * These releases all of the listeners on document.body. */ releaseMouseMoves() { - if (this._eventMoveToken && this._eventUpToken) { + if (this._eventMoveToken && this._eventUpToken && this._eventLeaveToken && this._eventOutToken) { this._eventMoveToken.remove(); this._eventMoveToken = null; this._eventUpToken.remove(); this._eventUpToken = null; + this._eventLeaveToken.remove(); + this._eventLeaveToken = null; + this._eventOutToken.remove(); + this._eventOutToken = null; } if (this._animationFrameID !== null) { @@ -139,7 +154,14 @@ class DOMMouseMoveTracker { if (this._animationFrameID) { this._didMouseMove(); } - this._onMoveEnd(); + this._onMoveEnd(false); + } + + /** + * Calls onMoveEnd passed into the constructor, updates internal state, and cancels the move. + */ + _onMouseEnd() { + this._onMoveEnd(true); } }