Fix bug with PressLegacy blur (#18194)
Dominic Gannaway committed
Mar 2, 2020 at 13:42 UTC
dbc7b9f50c9f4ff005c8ba6431adea9bec3d318a
4 files changed
+38
-17
packages/react-interactions/events/src/dom/PressLegacy.js
+3
-10
@@ -886,16 +886,9 @@ const pressResponderImpl = {
886
break;
887
}
888
case 'blur': {
889
- // If we encounter a blur event that moves focus to
890
- // the window, then the relatedTarget will be null.
891
- // In this case, we should cancel the active press.
892
- // Alternatively, if the blur target matches the
893
- // current pressed target, we should also cancel
894
- // the active press.
895
- if (
896
- isPressed &&
897
- (nativeEvent.relatedTarget === null || target === state.pressTarget)
898
- ) {
889
+ // If we encounter a blur that happens on the pressed target
890
+ // then disengage the blur.
891
+ if (isPressed && target === state.pressTarget) {
892
dispatchCancel(event, context, props, state);
893
}
894
}
packages/react-interactions/events/src/dom/Tap.js
+9
@@ -103,6 +103,7 @@ const rootEventTypes = hasPointerEvents
103
'pointermove',
104
'pointercancel',
105
'scroll',
106
+ 'blur',
107
]
108
: [
109
'click_active',
@@ -114,6 +115,7 @@ const rootEventTypes = hasPointerEvents
115
'touchmove',
116
'touchcancel',
117
'scroll',
118
+ 'blur',
119
];
120
121
/**
@@ -697,6 +699,13 @@ const responderImpl = {
699
removeRootEventTypes(context, state);
700
break;
701
}
702
+ case 'blur': {
703
+ // If we encounter a blur that happens on the pressed target
704
+ // then disengage the blur.
705
+ if (state.isActive && nativeEvent.target === state.responderTarget) {
706
+ dispatchCancel(context, props, state);
707
+ }
708
+ }
709
}
710
},
711
onUnmount(
packages/react-interactions/events/src/dom/__tests__/Press-test.internal.js
+21
@@ -700,4 +700,25 @@ describeWithPointerEvent('Press responder', hasPointerEvents => {
700
target.pointerup();
701
target.pointerdown();
702
});
703
+
704
+ it('when blur occurs on a pressed target, we should disengage press', () => {
705
+ const onPress = jest.fn();
706
+ const onPressStart = jest.fn();
707
+ const onPressEnd = jest.fn();
708
+ const buttonRef = React.createRef();
709
+
710
+ const Component = () => {
711
+ const listener = usePress({onPress, onPressStart, onPressEnd});
712
+ return <button ref={buttonRef} DEPRECATED_flareListeners={listener} />;
713
+ };
714
+ ReactDOM.render(<Component />, container);
715
+
716
+ const target = createEventTarget(buttonRef.current);
717
+ target.pointerdown();
718
+ expect(onPressStart).toBeCalled();
719
+ target.blur();
720
+ expect(onPressEnd).toBeCalled();
721
+ target.pointerup();
722
+ expect(onPress).not.toBeCalled();
723
+ });
724
});
packages/react-interactions/events/src/dom/__tests__/PressLegacy-test.internal.js
+5
-7
@@ -1173,10 +1173,10 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => {
1173
expect(onPressEnd).toBeCalled();
1174
});
1175
1176
- it('focus moving to the window should stop the press', () => {
1177
- const onPress = jest.fn(e => e.preventDefault());
1178
- const onPressStart = jest.fn(e => e.preventDefault());
1179
- const onPressEnd = jest.fn(e => e.preventDefault());
1176
+ it('when blur occurs on a pressed target, we should disengage press', () => {
1177
+ const onPress = jest.fn();
1178
+ const onPressStart = jest.fn();
1179
+ const onPressEnd = jest.fn();
1180
const buttonRef = React.createRef();
1181
1182
const Component = () => {
@@ -1187,10 +1187,8 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => {
1187
1188
const target = createEventTarget(buttonRef.current);
1189
target.pointerdown();
1190
- const secondTarget = createEventTarget(document);
1191
- // relatedTarget is null when moving focus to window
1190
expect(onPressStart).toBeCalled();
1193
- secondTarget.blur({relatedTarget: null});
1191
+ target.blur();
1192
expect(onPressEnd).toBeCalled();
1193
target.pointerup();
1194
expect(onPress).not.toBeCalled();