diff --git a/packages/react-native-web/src/modules/useResponderEvents/__tests__/index-test.js b/packages/react-native-web/src/modules/useResponderEvents/__tests__/index-test.js index 0fcf5325a..0af80d285 100644 --- a/packages/react-native-web/src/modules/useResponderEvents/__tests__/index-test.js +++ b/packages/react-native-web/src/modules/useResponderEvents/__tests__/index-test.js @@ -2385,6 +2385,91 @@ describe('useResponderEvents', () => { ]); }); + /** + * If a node is responder, then the negotiation with a sibling should + * capture to and bubble from the first common ancestor, even when that + * ancestor has no ancestors connected to the responder system. + */ + test('negotiate from first common ancestor when it has no responder ancestors', () => { + const pointerType = 'mouse'; + let eventLog = []; + const parentCallbacks = { + onMoveShouldSetResponderCapture() { + eventLog.push('parent: onMoveShouldSetResponderCapture'); + return false; + }, + onMoveShouldSetResponder() { + eventLog.push('parent: onMoveShouldSetResponder'); + return true; + }, + onResponderGrant() { + eventLog.push('parent: onResponderGrant'); + } + }; + const targetCallbacks = { + onStartShouldSetResponder() { + eventLog.push('target: onStartShouldSetResponder'); + return true; + }, + onResponderGrant() { + eventLog.push('target: onResponderGrant'); + }, + onResponderTerminationRequest() { + eventLog.push('target: onResponderTerminationRequest'); + return true; + }, + onResponderTerminate() { + eventLog.push('target: onResponderTerminate'); + } + }; + const siblingCallbacks = { + onStartShouldSetResponder() { + eventLog.push('sibling: onStartShouldSetResponder'); + return true; + } + }; + + const Component = () => { + useResponderEvents(parentRef, parentCallbacks); + useResponderEvents(targetRef, targetCallbacks); + useResponderEvents(siblingRef, siblingCallbacks); + return ( +