Skip to content

Commit 816dd4e

Browse files
authored
Complete Pressable refactor. (#3571)
## Description This PR introduces a complete `Pressable` refactor. New `Pressable` version defines sequences of events required to activate different `Pressable` callbacks. This approach allows for fewer edge-case controls, and features a much cleaner code base & a clear execution flow. The new implementation also makes detection and handling of new, unexpected cases much simpler. ### Fixes - Fixes #3476 - [`iOS`] Short taps were ignored when within a list - Ordering of `onPress*` was chaotic. Aligned it to [the documentation](https://reactnative.dev/docs/pressable#how-it-works). ### Completion checklist - `onPress*` - [x] callbacks - [x] support `hitSlop` (does not work on `MacOS`) - [x] support `pressRetentionOffset` - [x] support `unstable_pressDelay` - `onHover*` - [x] callback - [x] support `delayHoverIn`, `delayHoverOut` - `onLongPress` - [x] callback - [x] support `delayLongPress` - [x] ref passthrough support - `Android` - [x] works on `fabric` - [x] works on `paper` - `iOS` - Note: There's a `200ms` delay before `onPressIn` when long-pressing in a scroll list. This is an intentional "feature" within `iOS`, but RN `Pressable` manages to avoid it. - [x] works on `fabric` - [x] works on `paper` - [x] `Web` support - `MacOS` - [ ] works on `fabric` (could not test on my setup) - [x] works on `paper` - [x] `style` & `children` support ## Test plan Use all the existing Pressable examples to test the behaviour of the newly added pressable. Make sure to test on the following platforms: - `Android` fabric - `Android` paper - `iOS` fabric - `iOS` paper - `MacOS` fabric - `MacOS` paper - `Web` Make sure to also test the following scenarios: - `Pressable` is not nested, and is not within a `ScrollView` - `Pressable` is nested within another `Pressable`, without a `ScrollView` - `Pressable` is nested within another `Pressable`, which is nested within a RNGH `ScrollView` - `Pressable` is nested within another `Pressable`, which is nested within a RN `ScrollView` - `Pressable` is nested within another `Pressable`, which is nested within a `FlashList` - `Pressable` with `unstable_pressDelay`, `delayLongPress`, `hitSlop` & `pressRetentionOffset` props.
1 parent 6e31b0b commit 816dd4e

File tree

7 files changed

+591
-467
lines changed

7 files changed

+591
-467
lines changed

apps/common-app/src/new_api/pressable/index.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import React from 'react';
22
import { StyleSheet, Text, View } from 'react-native';
33
import { Pressable } from 'react-native-gesture-handler';
44

5+
const SECTION_RADIUS = 40;
6+
const BASE_SIZE = 120;
7+
58
export default function PressableExample() {
69
const pressIn = () => {
710
console.log('Pressable pressed in');
@@ -40,8 +43,8 @@ export default function PressableExample() {
4043
onHoverIn={hoverIn}
4144
onHoverOut={hoverOut}
4245
onLongPress={longPress}
43-
hitSlop={20}
44-
pressRetentionOffset={20}>
46+
hitSlop={SECTION_RADIUS}
47+
pressRetentionOffset={SECTION_RADIUS}>
4548
<View style={styles.textWrapper}>
4649
<Text style={styles.text}>Pressable!</Text>
4750
</View>
@@ -59,16 +62,16 @@ const BACKGROUND_COLOR = '#F5FCFF';
5962
const styles = StyleSheet.create({
6063
pressRectContainer: {
6164
backgroundColor: '#FFD6E0',
62-
padding: 20,
63-
width: 200,
64-
height: 200,
65+
padding: SECTION_RADIUS,
66+
width: BASE_SIZE + 4 * SECTION_RADIUS,
67+
height: BASE_SIZE + 4 * SECTION_RADIUS,
6568
margin: 'auto',
6669
},
6770
hitRectContainer: {
6871
backgroundColor: '#F29DC3',
69-
padding: 20,
70-
width: 160,
71-
height: 160,
72+
padding: SECTION_RADIUS,
73+
width: BASE_SIZE + 2 * SECTION_RADIUS,
74+
height: BASE_SIZE + 2 * SECTION_RADIUS,
7275
margin: 'auto',
7376
},
7477
rectText: {
@@ -79,13 +82,13 @@ const styles = StyleSheet.create({
7982
bottom: 2,
8083
},
8184
pressable: {
82-
width: 120,
83-
height: 120,
85+
width: BASE_SIZE,
86+
height: BASE_SIZE,
8487
backgroundColor: 'mediumpurple',
8588
},
8689
highlight: {
87-
width: 120,
88-
height: 120,
90+
width: BASE_SIZE,
91+
height: BASE_SIZE,
8992
backgroundColor: 'red',
9093
},
9194
textWrapper: {

apps/common-app/src/release_tests/nestedPressables/index.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,25 @@ function GesturizedBoxes() {
7979

8080
function LegacyBoxes() {
8181
return (
82-
<LegacyPressable style={outerStyle}>
83-
<LegacyPressable style={middleStyle}>
84-
<LegacyPressable style={innerStyle} />
82+
<LegacyPressable
83+
style={outerStyle}
84+
onPressIn={() => console.log('[outer] onPressIn')}
85+
onPressOut={() => console.log('[outer] onPressOut')}
86+
onPress={() => console.log('[outer] onPress')}
87+
onLongPress={() => console.log('[outer] onLongPress')}>
88+
<LegacyPressable
89+
style={middleStyle}
90+
onPressIn={() => console.log('[middle] onPressIn')}
91+
onPressOut={() => console.log('[middle] onPressOut')}
92+
onPress={() => console.log('[middle] onPress')}
93+
onLongPress={() => console.log('[middle] onLongPress')}>
94+
<LegacyPressable
95+
style={innerStyle}
96+
onPressIn={() => console.log('[inner] onPressIn')}
97+
onPressOut={() => console.log('[inner] onPressOut')}
98+
onPress={() => console.log('[inner] onPress')}
99+
onLongPress={() => console.log('[inner] onLongPress')}
100+
/>
85101
</LegacyPressable>
86102
</LegacyPressable>
87103
);

0 commit comments

Comments
 (0)