diff --git a/packages/react-interactions/events/src/dom/PressLegacy.js b/packages/react-interactions/events/src/dom/PressLegacy.js index 19ba8adda01af..d2c8c3d031b79 100644 --- a/packages/react-interactions/events/src/dom/PressLegacy.js +++ b/packages/react-interactions/events/src/dom/PressLegacy.js @@ -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); + } } } }, diff --git a/packages/react-interactions/events/src/dom/__tests__/PressLegacy-test.internal.js b/packages/react-interactions/events/src/dom/__tests__/PressLegacy-test.internal.js index 52969f0e68cff..65cb1141f8b11 100644 --- a/packages/react-interactions/events/src/dom/__tests__/PressLegacy-test.internal.js +++ b/packages/react-interactions/events/src/dom/__tests__/PressLegacy-test.internal.js @@ -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