feat: support pointerEvents (#655)

* test: add pointerEvents test

* feat: add pointerEvents handling

* test: add test for nested views

* feat: add pointerEvents box-none handling

* test: handle auto pointerEvents

* Update src/__tests__/fireEvent.test.js

Co-authored-by: Michał Pierzchała <thymikee@gmail.com>
This commit is contained in:
Michał
2021-02-05 15:05:46 +01:00
committed by GitHub
parent 34fc03a8c9
commit 2aa6609523
2 changed files with 95 additions and 0 deletions
+77
View File
@@ -234,6 +234,83 @@ 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();
const screen = render(
<View pointerEvents="none">
<Pressable onPress={handlePress}>
<Text>Trigger</Text>
</Pressable>
</View>
);
fireEvent.press(screen.getByText('Trigger'));
expect(handlePress).not.toHaveBeenCalled();
});
test('should not fire on box-only pointerEvents View', () => {
const handlePress = jest.fn();
const screen = render(
<View pointerEvents="box-only">
<Pressable onPress={handlePress}>
<Text>Trigger</Text>
</Pressable>
</View>
);
fireEvent.press(screen.getByText('Trigger'));
expect(handlePress).not.toHaveBeenCalled();
});
test('should fire on box-none pointerEvents View', () => {
const handlePress = jest.fn();
const screen = render(
<View pointerEvents="box-none">
<Pressable onPress={handlePress}>
<Text>Trigger</Text>
</Pressable>
</View>
);
fireEvent.press(screen.getByText('Trigger'));
expect(handlePress).toHaveBeenCalled();
});
test('should fire on auto pointerEvents View', () => {
const handlePress = jest.fn();
const screen = render(
<View pointerEvents="auto">
<Pressable onPress={handlePress}>
<Text>Trigger</Text>
</Pressable>
</View>
);
fireEvent.press(screen.getByText('Trigger'));
expect(handlePress).toHaveBeenCalled();
});
test('should not fire on box-only pointerEvents View with nested elements', () => {
const handlePress = jest.fn();
const screen = render(
<View pointerEvents="box-only">
<View>
<Pressable onPress={handlePress}>
<Text>Trigger</Text>
</Pressable>
</View>
</View>
);
fireEvent.press(screen.getByText('Trigger'));
expect(handlePress).not.toHaveBeenCalled();
});
test('should pass event up on disabled TouchableOpacity', () => {
const handleInnerPress = jest.fn();
const handleOuterPress = jest.fn();
+18
View File
@@ -17,11 +17,29 @@ const isTouchResponder = (element?: ReactTestInstance) => {
return !!element?.props.onStartShouldSetResponder || isTextInput(element);
};
const isPointerEventEnabled = (
element?: ReactTestInstance,
isParent?: boolean
) => {
const parentCondition = isParent
? element?.props.pointerEvents === 'box-only'
: element?.props.pointerEvents === 'box-none';
if (element?.props.pointerEvents === 'none' || parentCondition) {
return false;
}
if (!element?.parent) return true;
return isPointerEventEnabled(element.parent, true);
};
const isEventEnabled = (
element?: ReactTestInstance,
touchResponder?: ReactTestInstance
) => {
if (isTextInput(element)) return element?.props.editable !== false;
if (!isPointerEventEnabled(element)) return false;
const touchStart = touchResponder?.props.onStartShouldSetResponder?.();
const touchMove = touchResponder?.props.onMoveShouldSetResponder?.();