From 031eba789f0548838cf876b7c497f88aecec86f7 Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Mon, 9 Sep 2019 09:08:17 -0700 Subject: [PATCH] [react-events] Tap: change order of events (#16694) Before: start -> change -> update -> end (cancel) -> change Now: start -> change -> update -> change -> end (cancel) --- packages/react-events/src/dom/Tap.js | 8 +++---- .../src/dom/__tests__/Tap-test.internal.js | 24 +++++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/react-events/src/dom/Tap.js b/packages/react-events/src/dom/Tap.js index fe5ce0d91e65..2eb35938dbd2 100644 --- a/packages/react-events/src/dom/Tap.js +++ b/packages/react-events/src/dom/Tap.js @@ -573,6 +573,8 @@ const responderImpl = { state.gestureState = createGestureState(context, props, state, event); + state.isActive = false; + dispatchChange(context, props, state); if (context.isTargetWithinResponder(hitTarget)) { // Determine whether to call preventDefault on subsequent native events. if (isModifiedTap(event)) { @@ -582,8 +584,6 @@ const responderImpl = { } else { dispatchCancel(context, props, state); } - state.isActive = false; - dispatchChange(context, props, state); } if (!hasPointerEvents) { @@ -601,9 +601,9 @@ const responderImpl = { case 'dragstart': { if (state.isActive && isActivePointer(event, state)) { state.gestureState = createGestureState(context, props, state, event); - dispatchCancel(context, props, state); state.isActive = false; dispatchChange(context, props, state); + dispatchCancel(context, props, state); } break; } @@ -620,9 +620,9 @@ const responderImpl = { context.isTargetWithinNode(state.responderTarget, nativeEvent.target) ) { state.gestureState = createGestureState(context, props, state, event); - dispatchCancel(context, props, state); state.isActive = false; dispatchChange(context, props, state); + dispatchCancel(context, props, state); } break; } diff --git a/packages/react-events/src/dom/__tests__/Tap-test.internal.js b/packages/react-events/src/dom/__tests__/Tap-test.internal.js index bd8c051fe52f..b623f1b3d7c3 100644 --- a/packages/react-events/src/dom/__tests__/Tap-test.internal.js +++ b/packages/react-events/src/dom/__tests__/Tap-test.internal.js @@ -47,8 +47,8 @@ function tapAndMoveOutside({ // NOTE: this assumes the PointerEvent implementation calls // 'releasePointerCapture' for touch pointers if (!hasPointerEvents && pointerType === 'touch') { - downTarget.pointermove({pointerType, ...coordinatesOutside}); document.elementFromPoint = () => upTarget.node; + downTarget.pointermove({pointerType, ...coordinatesOutside}); } else { upTarget.pointermove({pointerType, ...coordinatesOutside}); } @@ -450,16 +450,30 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => { }); describe('onTapChange', () => { - let onTapChange, ref; + let eventsLog, onTapChange, ref; + + const logger = msg => () => { + eventsLog.push(msg); + }; beforeEach(() => { + eventsLog = []; onTapChange = jest.fn(); ref = React.createRef(); const Component = () => { - const listener = useTap({onTapChange}); + const listener = useTap({ + onTapChange(e) { + logger('change')(); + onTapChange(e); + }, + onTapStart: logger('start'), + onTapEnd: logger('end'), + onTapCancel: logger('cancel'), + }); return
; }; ReactDOM.render(, container); + document.elementFromPoint = () => ref.current; }); testWithPointerType('pointer down/up', pointerType => { @@ -467,9 +481,10 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => { target.pointerdown({pointerType}); expect(onTapChange).toHaveBeenCalledTimes(1); expect(onTapChange).toHaveBeenCalledWith(true); - target.pointerup({pointerType}); + target.pointerup({pointerType, x: 0, y: 0}); expect(onTapChange).toHaveBeenCalledTimes(2); expect(onTapChange).toHaveBeenCalledWith(false); + expect(eventsLog).toEqual(['start', 'change', 'change', 'end']); }); testWithPointerType('pointer cancel', pointerType => { @@ -480,6 +495,7 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => { target.pointercancel({pointerType}); expect(onTapChange).toHaveBeenCalledTimes(2); expect(onTapChange).toHaveBeenCalledWith(false); + expect(eventsLog).toEqual(['start', 'change', 'change', 'cancel']); }); testWithPointerType('pointer move outside target', pointerType => {