From 0e0664f7d0220b453af3ba324f8faa4511a96ae4 Mon Sep 17 00:00:00 2001 From: David Calhoun <438664+dcalhoun@users.noreply.github.com> Date: Sat, 22 Jan 2022 08:28:46 -0600 Subject: [PATCH 1/3] Trigger non-touch events on box-none targets Currently, this library disables _all_ events for a target with `pointerEvents="box-none"`. This behavior is counter to how React Native itself functions. This change continues to disable touch events, e.g. `press`, for targets set to "box-none", but allows triggering non-touch events, e.g. `layout`, `touchStart`. --- src/__tests__/fireEvent.test.js | 30 ++++++++++++++++++++++++++++++ src/fireEvent.js | 12 +++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index e21da6835..a64ee48a9 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -317,6 +317,36 @@ test('should not fire on box-only pointerEvents View with nested elements', () = expect(handlePress).not.toHaveBeenCalled(); }); +test('should fire non-terminal touch events on box-none pointerEvents View', () => { + const handleTouchStart = jest.fn(); + + const screen = render( + + {}}> + Trigger + + + ); + + fireEvent(screen.getByText('Trigger'), 'touchStart'); + expect(handleTouchStart).toHaveBeenCalled(); +}); + +test('should fire non-touch events on box-none pointerEvents View', () => { + const handleLayout = jest.fn(); + + const screen = render( + + {}}> + Trigger + + + ); + + fireEvent(screen.getByText('Trigger'), 'layout'); + expect(handleLayout).toHaveBeenCalled(); +}); + test('should pass event up on disabled TouchableOpacity', () => { const handleInnerPress = jest.fn(); const handleOuterPress = jest.fn(); diff --git a/src/fireEvent.js b/src/fireEvent.js index 8447c4b8c..e4237c315 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -33,12 +33,17 @@ const isPointerEventEnabled = ( return isPointerEventEnabled(element.parent, true); }; +const isTouchEvent = (eventName?: string) => { + return eventName === 'press'; +}; + const isEventEnabled = ( element?: ReactTestInstance, - touchResponder?: ReactTestInstance + touchResponder?: ReactTestInstance, + eventName?: string ) => { if (isTextInput(element)) return element?.props.editable !== false; - if (!isPointerEventEnabled(element)) return false; + if (!isPointerEventEnabled(element) && isTouchEvent(eventName)) return false; const touchStart = touchResponder?.props.onStartShouldSetResponder?.(); const touchMove = touchResponder?.props.onMoveShouldSetResponder?.(); @@ -59,7 +64,8 @@ const findEventHandler = ( : nearestTouchResponder; const handler = getEventHandler(element, eventName); - if (handler && isEventEnabled(element, touchResponder)) return handler; + if (handler && isEventEnabled(element, touchResponder, eventName)) + return handler; if (element.parent === null || element.parent.parent === null) { return null; From dd08c318144cf6b9dfad6f248e6af6d5bde22939 Mon Sep 17 00:00:00 2001 From: David Calhoun <438664+dcalhoun@users.noreply.github.com> Date: Sat, 22 Jan 2022 15:56:03 -0600 Subject: [PATCH 2/3] Event triggers target box-none View instead of child This approach more closely aligns with the original failing test case. --- src/__tests__/fireEvent.test.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index a64ee48a9..729329cb8 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -321,14 +321,18 @@ test('should fire non-terminal touch events on box-none pointerEvents View', () const handleTouchStart = jest.fn(); const screen = render( - + {}}> Trigger ); - fireEvent(screen.getByText('Trigger'), 'touchStart'); + fireEvent(screen.getByTestId('touch-start-view'), 'touchStart'); expect(handleTouchStart).toHaveBeenCalled(); }); @@ -336,14 +340,14 @@ test('should fire non-touch events on box-none pointerEvents View', () => { const handleLayout = jest.fn(); const screen = render( - + {}}> Trigger ); - fireEvent(screen.getByText('Trigger'), 'layout'); + fireEvent(screen.getByTestId('layout-view'), 'layout'); expect(handleLayout).toHaveBeenCalled(); }); From 4e589225178cd9b3aefdfe26bc66ae0d89eb415c Mon Sep 17 00:00:00 2001 From: David Calhoun <438664+dcalhoun@users.noreply.github.com> Date: Thu, 27 Jan 2022 08:29:27 -0600 Subject: [PATCH 3/3] Rename events in test description Attempt to better communicate the test is focused on ensuring that touch events continue to trigger (e.g. `touchStart`), but the final event from a touch tap does not trigger. --- src/__tests__/fireEvent.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index 729329cb8..908b338e0 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -317,7 +317,7 @@ test('should not fire on box-only pointerEvents View with nested elements', () = expect(handlePress).not.toHaveBeenCalled(); }); -test('should fire non-terminal touch events on box-none pointerEvents View', () => { +test('should fire non-pointer events on box-none pointerEvents View', () => { const handleTouchStart = jest.fn(); const screen = render(