mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[react-interactions] Ensure blur to window disengages press (#18125)
This commit is contained in:
@@ -126,6 +126,7 @@ const rootEventTypes = hasPointerEvents
|
||||
'click',
|
||||
'keyup',
|
||||
'scroll',
|
||||
'blur',
|
||||
]
|
||||
: [
|
||||
'click',
|
||||
@@ -138,6 +139,7 @@ const rootEventTypes = hasPointerEvents
|
||||
'dragstart',
|
||||
'mouseup_active',
|
||||
'touchend',
|
||||
'blur',
|
||||
];
|
||||
|
||||
function isFunction(obj): boolean {
|
||||
@@ -881,6 +883,21 @@ const pressResponderImpl = {
|
||||
case 'touchcancel':
|
||||
case 'dragstart': {
|
||||
dispatchCancel(event, context, props, state);
|
||||
break;
|
||||
}
|
||||
case 'blur': {
|
||||
// If we encounter a blur event that moves focus to
|
||||
// the window, then the relatedTarget will be null.
|
||||
// In this case, we should cancel the active press.
|
||||
// Alternatively, if the blur target matches the
|
||||
// current pressed target, we should also cancel
|
||||
// the active press.
|
||||
if (
|
||||
isPressed &&
|
||||
(nativeEvent.relatedTarget === null || target === state.pressTarget)
|
||||
) {
|
||||
dispatchCancel(event, context, props, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1167,4 +1167,27 @@ describe.each(environmentTable)('Press responder', hasPointerEvents => {
|
||||
expect(onPressStart).toBeCalled();
|
||||
expect(onPressEnd).toBeCalled();
|
||||
});
|
||||
|
||||
it('focus moving to the window should stop the press', () => {
|
||||
const onPress = jest.fn(e => e.preventDefault());
|
||||
const onPressStart = jest.fn(e => e.preventDefault());
|
||||
const onPressEnd = jest.fn(e => e.preventDefault());
|
||||
const buttonRef = React.createRef();
|
||||
|
||||
const Component = () => {
|
||||
const listener = usePress({onPress, onPressStart, onPressEnd});
|
||||
return <button ref={buttonRef} DEPRECATED_flareListeners={listener} />;
|
||||
};
|
||||
ReactDOM.render(<Component />, container);
|
||||
|
||||
const target = createEventTarget(buttonRef.current);
|
||||
target.pointerdown();
|
||||
const secondTarget = createEventTarget(document);
|
||||
// relatedTarget is null when moving focus to window
|
||||
expect(onPressStart).toBeCalled();
|
||||
secondTarget.blur({relatedTarget: null});
|
||||
expect(onPressEnd).toBeCalled();
|
||||
target.pointerup();
|
||||
expect(onPress).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user