Skip to content

Commit d731d83

Browse files
committed
feat: modern fireEvent.press
1 parent 0b69f6b commit d731d83

10 files changed

Lines changed: 737 additions & 48 deletions

File tree

‎src/events/__tests__/fire-event.test.tsx‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,19 @@ test('fireEvent.changeText', async () => {
6060
);
6161
});
6262

63-
test('fireEvent.press uses the legacy implementation', async () => {
63+
test('fireEvent.press calls onPress of Pressable with the event of the selected event system', async () => {
6464
const onPress = jest.fn();
6565
await render(
6666
<Pressable testID="pressable" onPress={onPress}>
6767
<Text>Press me</Text>
6868
</Pressable>,
6969
);
7070

71-
expect(await fireEvent.press(screen.getByText('Press me'))).toBeUndefined();
71+
const result = await fireEvent.press(screen.getByText('Press me'));
72+
const isModern = getConfig().unstable_eventSystem === 'modern';
73+
expect(result).toBe(isModern ? true : undefined);
7274
expect(onPress).toHaveBeenCalledTimes(1);
73-
expect(onPress.mock.calls[0][0]).not.toBeInstanceOf(SyntheticEvent);
75+
expect(onPress.mock.calls[0][0] instanceof SyntheticEvent).toBe(isModern);
7476
});
7577

7678
test('fireEvent.scroll and fireEvent.layout pass events of the selected event system', async () => {

‎src/events/fire-event.ts‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ fireEvent.changeText = async (instance: TestInstance, text: string): Promise<unk
3232
return await legacyFireEvent.changeText(instance, text);
3333
};
3434

35-
// Legacy in both event systems for now: `Pressable` and `Touchable*` get touches through the
36-
// responder system, which the modern event system doesn't implement yet.
37-
fireEvent.press = async (instance: TestInstance, eventProps?: EventProps): Promise<void> => {
35+
fireEvent.press = async (
36+
instance: TestInstance,
37+
eventProps?: EventProps,
38+
): Promise<boolean | undefined> => {
39+
if (isModern()) {
40+
return await modernFireEvent.press(instance, eventProps as FireEventInit);
41+
}
42+
3843
await legacyFireEvent.press(instance, eventProps);
44+
return undefined;
3945
};
4046

4147
fireEvent.scroll = async (

‎src/events/legacy/index.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export * from './builders/common';
22
export * from '../shared/handler';
3-
export { isPointerEventEnabled } from './is-enabled';
3+
export { isPointerEventEnabled } from '../shared/pointer-events';
44
export * from '../shared/native-state';
55
export type { EventWarning } from './warnings';
66
export { formatDisabledTargets, getPointerEventsBlockedTargets, logEventWarning } from './warnings';

‎src/events/legacy/is-enabled.ts‎

Lines changed: 1 addition & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,8 @@
1-
import { StyleSheet } from 'react-native';
21
import type { TestInstance } from 'test-renderer';
32

43
import { isHostTextInput } from '../../helpers/host-component-names';
54
import { isEditableTextInput } from '../../helpers/text-input';
6-
7-
/**
8-
* pointerEvents controls whether the View can be the target of touch events.
9-
* 'auto': The View and its children can be the target of touch events.
10-
* 'none': The View is never the target of touch events.
11-
* 'box-none': The View is never the target of touch events but its subviews can be
12-
* 'box-only': The view can be the target of touch events but its subviews cannot be
13-
* see the official react native doc https://reactnative.dev/docs/view#pointerevents */
14-
export function isPointerEventEnabled(instance: TestInstance): boolean {
15-
return getPointerEventsBlocker(instance) == null;
16-
}
17-
18-
/**
19-
* Returns the element whose `pointerEvents` prevents the instance from being the target of
20-
* touch events: the instance itself or one of its ancestors. Returns `null` if nothing blocks it.
21-
*/
22-
export function getPointerEventsBlocker(instance: TestInstance): TestInstance | null {
23-
return findPointerEventsBlocker(instance, false);
24-
}
5+
import { isPointerEventEnabled } from '../shared/pointer-events';
256

267
export function isTouchResponder(instance: TestInstance) {
278
return Boolean(instance.props.onStartShouldSetResponder) || isHostTextInput(instance);
@@ -73,21 +54,3 @@ export function isEventEnabled(
7354

7455
return touchStart === undefined && touchMove === undefined;
7556
}
76-
77-
function findPointerEventsBlocker(instance: TestInstance, isParent: boolean): TestInstance | null {
78-
// Check both props.pointerEvents and props.style.pointerEvents
79-
const pointerEvents =
80-
instance?.props.pointerEvents ?? StyleSheet.flatten(instance?.props.style)?.pointerEvents;
81-
82-
const parentCondition = isParent ? pointerEvents === 'box-only' : pointerEvents === 'box-none';
83-
84-
if (pointerEvents === 'none' || parentCondition) {
85-
return instance;
86-
}
87-
88-
if (!instance.parent) {
89-
return null;
90-
}
91-
92-
return findPointerEventsBlocker(instance.parent, true);
93-
}

‎src/events/legacy/warnings.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import { isHostTextInput } from '../../helpers/host-component-names';
88
import { logger } from '../../helpers/logger';
99
import { isEditableTextInput } from '../../helpers/text-input';
1010
import { getEventHandlerName, normalizeEventType } from '../shared/handler';
11-
import { getPointerEventsBlocker, isEventBlockableByPointerEvents } from './is-enabled';
11+
import { getPointerEventsBlocker } from '../shared/pointer-events';
12+
import { isEventBlockableByPointerEvents } from './is-enabled';
1213

1314
type UnhandledEventInfo = {
1415
skippedTargets: TestInstance[];

0 commit comments

Comments
 (0)