From 8d95806197f0425f8747be977433fb13d466f618 Mon Sep 17 00:00:00 2001 From: Samuel Reed Date: Wed, 29 Jul 2020 17:33:23 -0400 Subject: [PATCH] fix(grid): incorrect `x` and `y` passed to onStop This was caused by `onStop` erroneously recalculating coordinates, which is not necessary / should not happen in the real world, as `mouseup` and `touchend` should not pass `clientX` and `clientY` values meaningfully different than the last corresponding move event. In fact, they are already ignored by ``. For this reason, we can simply trust the `lastX` and `lastY` in `onDragStop`, and pass those back. Fixes #413, bokuweb/react-rnd#453 --- lib/DraggableCore.js | 7 ++---- specs/draggable.spec.jsx | 50 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/lib/DraggableCore.js b/lib/DraggableCore.js index 2260fa5a..7f47879b 100644 --- a/lib/DraggableCore.js +++ b/lib/DraggableCore.js @@ -381,11 +381,8 @@ export default class DraggableCore extends React.Component = (e) => { if (!this.state.dragging) return; - - const position = getControlPosition(e, this.state.touchIdentifier, this); - if (position == null) return; - const {x, y} = position; - const coreEvent = createCoreData(this, x, y); + // No dragging is possible on stop, so we just echo back lastX & lastY. + const coreEvent = createCoreData(this, this.state.lastX, this.state.lastY); // Call event handler const shouldContinue = this.props.onStop(e, coreEvent); diff --git a/specs/draggable.spec.jsx b/specs/draggable.spec.jsx index a7a1f104..d05d90d9 100644 --- a/specs/draggable.spec.jsx +++ b/specs/draggable.spec.jsx @@ -153,6 +153,54 @@ describe('react-draggable', function () { simulateMovementFromTo(drag, 0, 0, 100, 100); }); + // https://github.com/STRML/react-draggable/issues/413 + it('should adjust draggable data output when `grid` prop supplied', function () { + let dragCount = 0; + function onDrag(event, data) { + if (dragCount === 0) { + // Should be 150, not 160 + assert(data.x === 150); + assert(data.y === 150); + assert(data.lastX === 0); + assert(data.lastY === 0); + } else { + // Should be 200, not 180 (snaps) + assert(data.x === 200); + assert(data.y === 150); + assert(data.lastX === 150); + assert(data.lastY === 150); + } + } + function onDragStop(event, data) { + if (dragCount === 0) { + assert(data.x === 150); + assert(data.y === 150); + // As this is another step: drag, then dragStop + // dragStops lastX always === x + assert(data.lastX === 150); + assert(data.lastY === 150); + } else { + assert(data.x === 200); + assert(data.y === 150); + assert(data.lastX === 200); + assert(data.lastY === 150); + } + } + drag = TestUtils.renderIntoDocument( + +
+ + ); + + simulateMovementFromTo(drag, 0, 0, 160, 160); + // then, move again, should snap `x` to 200 + dragCount++; + simulateMovementFromTo(drag, 150, 150, 180, 160); + }); + it('should throw when setting className', function () { drag = (); @@ -959,7 +1007,7 @@ function simulateMovementFromTo(drag, fromX, fromY, toX, toY) { TestUtils.Simulate.mouseDown(node, {clientX: fromX, clientY: fromX}); mouseMove(toX, toY, node); - TestUtils.Simulate.mouseUp(node); + TestUtils.Simulate.mouseUp(node, {clientX: toX, clientY: toY}); } function fragmentFromString(strHTML) {