Skip to content

Commit

Permalink
Trigger non-touch events on box-none targets
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
dcalhoun committed Jan 22, 2022
1 parent a010ffd commit 0e0664f
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
30 changes: 30 additions & 0 deletions src/__tests__/fireEvent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<View pointerEvents="box-none" onTouchStart={handleTouchStart}>
<Pressable onPress={() => {}}>
<Text>Trigger</Text>
</Pressable>
</View>
);

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(
<View pointerEvents="box-none" onLayout={handleLayout}>
<Pressable onPress={() => {}}>
<Text>Trigger</Text>
</Pressable>
</View>
);

fireEvent(screen.getByText('Trigger'), 'layout');
expect(handleLayout).toHaveBeenCalled();
});

test('should pass event up on disabled TouchableOpacity', () => {
const handleInnerPress = jest.fn();
const handleOuterPress = jest.fn();
Expand Down
12 changes: 9 additions & 3 deletions src/fireEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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?.();
Expand All @@ -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;
Expand Down

0 comments on commit 0e0664f

Please sign in to comment.