Skip to content

Commit

Permalink
[react-interactions] Ensure blur to window disengages press (#18125)
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Feb 25, 2020
1 parent bf13d3e commit a29a273
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
17 changes: 17 additions & 0 deletions packages/react-interactions/events/src/dom/PressLegacy.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const rootEventTypes = hasPointerEvents
'click',
'keyup',
'scroll',
'blur',
]
: [
'click',
Expand All @@ -138,6 +139,7 @@ const rootEventTypes = hasPointerEvents
'dragstart',
'mouseup_active',
'touchend',
'blur',
];

function isFunction(obj): boolean {
Expand Down Expand Up @@ -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);
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
});
});

0 comments on commit a29a273

Please sign in to comment.