[react-events] Tap: change order of events (#16694)
Before: start -> change -> update -> end (cancel) -> change Now: start -> change -> update -> change -> end (cancel)
Nicolas Gallagher committed
Sep 9, 2019 at 09:08 UTC
031eba789f0548838cf876b7c497f88aecec86f7
2 files changed
+24
-8
packages/react-events/src/dom/Tap.js
+4
-4
@@ -573,6 +573,8 @@ const responderImpl = {
573
574
state.gestureState = createGestureState(context, props, state, event);
575
576
+ state.isActive = false;
577
+ dispatchChange(context, props, state);
578
if (context.isTargetWithinResponder(hitTarget)) {
579
// Determine whether to call preventDefault on subsequent native events.
580
if (isModifiedTap(event)) {
@@ -582,8 +584,6 @@ const responderImpl = {
584
} else {
585
dispatchCancel(context, props, state);
586
}
585
- state.isActive = false;
586
- dispatchChange(context, props, state);
587
}
588
589
if (!hasPointerEvents) {
@@ -601,9 +601,9 @@ const responderImpl = {
601
case 'dragstart': {
602
if (state.isActive && isActivePointer(event, state)) {
603
state.gestureState = createGestureState(context, props, state, event);
604
- dispatchCancel(context, props, state);
604
state.isActive = false;
605
dispatchChange(context, props, state);
606
+ dispatchCancel(context, props, state);
607
}
608
break;
609
}
@@ -620,9 +620,9 @@ const responderImpl = {
620
context.isTargetWithinNode(state.responderTarget, nativeEvent.target)
621
) {
622
state.gestureState = createGestureState(context, props, state, event);
623
- dispatchCancel(context, props, state);
623
state.isActive = false;
624
dispatchChange(context, props, state);
625
+ dispatchCancel(context, props, state);
626
}
627
break;
628
}
packages/react-events/src/dom/__tests__/Tap-test.internal.js
+20
-4
@@ -47,8 +47,8 @@ function tapAndMoveOutside({
47
// NOTE: this assumes the PointerEvent implementation calls
48
// 'releasePointerCapture' for touch pointers
49
if (!hasPointerEvents && pointerType === 'touch') {
50
- downTarget.pointermove({pointerType, ...coordinatesOutside});
50
document.elementFromPoint = () => upTarget.node;
51
+ downTarget.pointermove({pointerType, ...coordinatesOutside});
52
} else {
53
upTarget.pointermove({pointerType, ...coordinatesOutside});
54
}
@@ -450,16 +450,30 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => {
450
});
451
452
describe('onTapChange', () => {
453
- let onTapChange, ref;
453
+ let eventsLog, onTapChange, ref;
454
+
455
+ const logger = msg => () => {
456
+ eventsLog.push(msg);
457
+ };
458
459
beforeEach(() => {
460
+ eventsLog = [];
461
onTapChange = jest.fn();
462
ref = React.createRef();
463
const Component = () => {
459
- const listener = useTap({onTapChange});
464
+ const listener = useTap({
465
+ onTapChange(e) {
466
+ logger('change')();
467
+ onTapChange(e);
468
+ },
469
+ onTapStart: logger('start'),
470
+ onTapEnd: logger('end'),
471
+ onTapCancel: logger('cancel'),
472
+ });
473
return <div ref={ref} listeners={listener} />;
474
};
475
ReactDOM.render(<Component />, container);
476
+ document.elementFromPoint = () => ref.current;
477
});
478
479
testWithPointerType('pointer down/up', pointerType => {
@@ -467,9 +481,10 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => {
481
target.pointerdown({pointerType});
482
expect(onTapChange).toHaveBeenCalledTimes(1);
483
expect(onTapChange).toHaveBeenCalledWith(true);
470
- target.pointerup({pointerType});
484
+ target.pointerup({pointerType, x: 0, y: 0});
485
expect(onTapChange).toHaveBeenCalledTimes(2);
486
expect(onTapChange).toHaveBeenCalledWith(false);
487
+ expect(eventsLog).toEqual(['start', 'change', 'change', 'end']);
488
});
489
490
testWithPointerType('pointer cancel', pointerType => {
@@ -480,6 +495,7 @@ describeWithPointerEvent('Tap responder', hasPointerEvents => {
495
target.pointercancel({pointerType});
496
expect(onTapChange).toHaveBeenCalledTimes(2);
497
expect(onTapChange).toHaveBeenCalledWith(false);
498
+ expect(eventsLog).toEqual(['start', 'change', 'change', 'cancel']);
499
});
500
501
testWithPointerType('pointer move outside target', pointerType => {