diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx
index ce6266dfe..6e9fb8f01 100644
--- a/src/__tests__/fireEvent.test.tsx
+++ b/src/__tests__/fireEvent.test.tsx
@@ -254,73 +254,68 @@ test('should not fire on non-editable TextInput with nested Text', () => {
expect(onChangeTextMock).not.toHaveBeenCalled();
});
-test('should not fire on none pointerEvents View', () => {
- const handlePress = jest.fn();
-
+test('should not fire inside View with pointerEvents="none"', () => {
+ const onPress = jest.fn();
const screen = render(
-
+
Trigger
);
fireEvent.press(screen.getByText('Trigger'));
- expect(handlePress).not.toHaveBeenCalled();
+ expect(onPress).not.toHaveBeenCalled();
});
-test('should not fire on box-only pointerEvents View', () => {
- const handlePress = jest.fn();
-
+test('should not fire inside View with pointerEvents="box-only"', () => {
+ const onPress = jest.fn();
const screen = render(
-
+
Trigger
);
fireEvent.press(screen.getByText('Trigger'));
- expect(handlePress).not.toHaveBeenCalled();
+ expect(onPress).not.toHaveBeenCalled();
});
-test('should fire on box-none pointerEvents View', () => {
- const handlePress = jest.fn();
-
+test('should fire inside View with pointerEvents="box-none"', () => {
+ const onPress = jest.fn();
const screen = render(
-
+
Trigger
);
fireEvent.press(screen.getByText('Trigger'));
- expect(handlePress).toHaveBeenCalled();
+ expect(onPress).toHaveBeenCalled();
});
-test('should fire on auto pointerEvents View', () => {
- const handlePress = jest.fn();
-
+test('should fire inside View with pointerEvents="auto"', () => {
+ const onPress = jest.fn();
const screen = render(
-
+
Trigger
);
fireEvent.press(screen.getByText('Trigger'));
- expect(handlePress).toHaveBeenCalled();
+ expect(onPress).toHaveBeenCalled();
});
-test('should not fire on box-only pointerEvents View with nested elements', () => {
- const handlePress = jest.fn();
-
+test('should not fire deeply inside View with pointerEvents="box-only"', () => {
+ const onPress = jest.fn();
const screen = render(
-
+
Trigger
@@ -328,41 +323,39 @@ test('should not fire on box-only pointerEvents View with nested elements', () =
);
fireEvent.press(screen.getByText('Trigger'));
- expect(handlePress).not.toHaveBeenCalled();
+ expect(onPress).not.toHaveBeenCalled();
});
-test('should fire non-pointer events on box-none pointerEvents View', () => {
- const handleTouchStart = jest.fn();
-
+test('should fire non-pointer events inside View with pointerEvents="box-none"', () => {
+ const onTouchStart = jest.fn();
const screen = render(
-
- {}}>
- Trigger
-
-
+
);
- fireEvent(screen.getByTestId('touch-start-view'), 'touchStart');
- expect(handleTouchStart).toHaveBeenCalled();
+ fireEvent(screen.getByTestId('view'), 'touchStart');
+ expect(onTouchStart).toHaveBeenCalled();
});
-test('should fire non-touch events on box-none pointerEvents View', () => {
- const handleLayout = jest.fn();
+test('should fire non-touch events inside View with pointerEvents="box-none"', () => {
+ const onLayout = jest.fn();
+ const screen = render(
+
+ );
+
+ fireEvent(screen.getByTestId('view'), 'layout');
+ expect(onLayout).toHaveBeenCalled();
+});
+// This test if pointerEvents="box-only" on composite `Pressable` is blocking
+// the 'press' event on host View rendered by pressable.
+test('should fire on Pressable with pointerEvents="box-only', () => {
+ const onPress = jest.fn();
const screen = render(
-
- {}}>
- Trigger
-
-
+
);
- fireEvent(screen.getByTestId('layout-view'), 'layout');
- expect(handleLayout).toHaveBeenCalled();
+ fireEvent.press(screen.getByTestId('pressable'));
+ expect(onPress).toHaveBeenCalled();
});
test('should pass event up on disabled TouchableOpacity', () => {
diff --git a/src/fireEvent.ts b/src/fireEvent.ts
index e60398bc1..eb5ce8c28 100644
--- a/src/fireEvent.ts
+++ b/src/fireEvent.ts
@@ -1,7 +1,7 @@
import { ReactTestInstance } from 'react-test-renderer';
import { TextInput } from 'react-native';
import act from './act';
-import { isHostElement } from './helpers/component-tree';
+import { getHostParent, isHostElement } from './helpers/component-tree';
import { filterNodeByType } from './helpers/filterNodeByType';
import { getHostComponentNames } from './helpers/host-component-names';
@@ -29,20 +29,24 @@ const isTouchResponder = (element?: ReactTestInstance) => {
};
const isPointerEventEnabled = (
- element?: ReactTestInstance,
+ element: ReactTestInstance,
isParent?: boolean
): boolean => {
- const parentCondition = isParent
- ? element?.props.pointerEvents === 'box-only'
- : element?.props.pointerEvents === 'box-none';
+ const pointerEvents = element.props.pointerEvents;
+ if (pointerEvents === 'none') {
+ return false;
+ }
- if (element?.props.pointerEvents === 'none' || parentCondition) {
+ if (isParent ? pointerEvents === 'box-only' : pointerEvents === 'box-none') {
return false;
}
- if (!element?.parent) return true;
+ const parent = getHostParent(element);
+ if (!parent) {
+ return true;
+ }
- return isPointerEventEnabled(element.parent, true);
+ return isPointerEventEnabled(parent, true);
};
const isTouchEvent = (eventName?: string) => {
@@ -50,7 +54,7 @@ const isTouchEvent = (eventName?: string) => {
};
const isEventEnabled = (
- element?: ReactTestInstance,
+ element: ReactTestInstance,
touchResponder?: ReactTestInstance,
eventName?: string
) => {