Skip to content

Commit ac3820a

Browse files
authored
refactor: replace TouchableWithoutFeedback with Pressable (#4117)
1 parent b2311ef commit ac3820a

File tree

15 files changed

+791
-198
lines changed

15 files changed

+791
-198
lines changed

example/src/Examples/ChipExample.tsx

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import { useExampleTheme } from '..';
1515
import ScreenWrapper from '../ScreenWrapper';
1616

1717
const ChipExample = () => {
18-
const [visible, setVisible] = React.useState<boolean>(false);
18+
const [snackbarProperties, setSnackbarProperties] = React.useState({
19+
visible: false,
20+
text: '',
21+
});
1922
const { isV3 } = useExampleTheme();
2023
const customColor = isV3 ? MD3Colors.error50 : MD2Colors.purple900;
2124

@@ -47,7 +50,12 @@ const ChipExample = () => {
4750
)}
4851
<Chip
4952
onPress={() => {}}
50-
onClose={() => {}}
53+
onClose={() =>
54+
setSnackbarProperties({
55+
visible: true,
56+
text: 'Close button pressed',
57+
})
58+
}
5159
style={styles.chip}
5260
closeIconAccessibilityLabel="Close icon accessibility label"
5361
>
@@ -56,7 +64,12 @@ const ChipExample = () => {
5664
<Chip
5765
icon="heart"
5866
onPress={() => {}}
59-
onClose={() => {}}
67+
onClose={() =>
68+
setSnackbarProperties({
69+
visible: true,
70+
text: 'Heart icon close button pressed',
71+
})
72+
}
6073
style={styles.chip}
6174
>
6275
Icon
@@ -69,7 +82,12 @@ const ChipExample = () => {
6982
/>
7083
}
7184
onPress={() => {}}
72-
onClose={() => {}}
85+
onClose={() =>
86+
setSnackbarProperties({
87+
visible: true,
88+
text: 'Avatar close button pressed',
89+
})
90+
}
7391
style={styles.chip}
7492
>
7593
Avatar
@@ -87,7 +105,17 @@ const ChipExample = () => {
87105
>
88106
Avatar (selected)
89107
</Chip>
90-
<Chip disabled icon="heart" onClose={() => {}} style={styles.chip}>
108+
<Chip
109+
disabled
110+
icon="heart"
111+
onClose={() =>
112+
setSnackbarProperties({
113+
visible: true,
114+
text: 'Disabled heart icon close button pressed',
115+
})
116+
}
117+
style={styles.chip}
118+
>
91119
Icon (disabled)
92120
</Chip>
93121
<Chip
@@ -141,7 +169,12 @@ const ChipExample = () => {
141169
<Chip
142170
mode="outlined"
143171
onPress={() => {}}
144-
onClose={() => {}}
172+
onClose={() =>
173+
setSnackbarProperties({
174+
visible: true,
175+
text: 'Close button pressed',
176+
})
177+
}
145178
style={styles.chip}
146179
>
147180
Close button
@@ -150,7 +183,12 @@ const ChipExample = () => {
150183
mode="outlined"
151184
icon="heart"
152185
onPress={() => {}}
153-
onClose={() => {}}
186+
onClose={() =>
187+
setSnackbarProperties({
188+
visible: true,
189+
text: 'Heart icon close button pressed',
190+
})
191+
}
154192
style={styles.chip}
155193
>
156194
Icon
@@ -186,7 +224,12 @@ const ChipExample = () => {
186224
disabled
187225
mode="outlined"
188226
icon="heart"
189-
onClose={() => {}}
227+
onClose={() =>
228+
setSnackbarProperties({
229+
visible: true,
230+
text: 'Disabled close button pressed',
231+
})
232+
}
190233
style={styles.chip}
191234
>
192235
Icon (disabled)
@@ -243,7 +286,9 @@ const ChipExample = () => {
243286
<Chip
244287
mode="outlined"
245288
onPress={() => {}}
246-
onLongPress={() => setVisible(true)}
289+
onLongPress={() =>
290+
setSnackbarProperties({ visible: true, text: '' })
291+
}
247292
style={styles.chip}
248293
>
249294
With onLongPress
@@ -299,7 +344,12 @@ const ChipExample = () => {
299344
</Chip>
300345
<Chip
301346
onPress={() => {}}
302-
onClose={() => {}}
347+
onClose={() =>
348+
setSnackbarProperties({
349+
visible: true,
350+
text: 'Close button pressed',
351+
})
352+
}
303353
style={styles.bigTextFlex}
304354
textStyle={styles.bigTextStyle}
305355
ellipsizeMode="middle"
@@ -310,7 +360,12 @@ const ChipExample = () => {
310360
</Chip>
311361
<Chip
312362
onPress={() => {}}
313-
onClose={() => {}}
363+
onClose={() =>
364+
setSnackbarProperties({
365+
visible: true,
366+
text: 'Custom icon close button pressed',
367+
})
368+
}
314369
closeIcon="arrow-down"
315370
style={styles.chip}
316371
closeIconAccessibilityLabel="Custom Close icon accessibility label"
@@ -331,11 +386,11 @@ const ChipExample = () => {
331386
</List.Section>
332387
</ScreenWrapper>
333388
<Snackbar
334-
visible={visible}
335-
onDismiss={() => setVisible(false)}
389+
visible={snackbarProperties.visible}
390+
onDismiss={() => setSnackbarProperties({ visible: false, text: '' })}
336391
duration={Snackbar.DURATION_SHORT}
337392
>
338-
onLongPress activated!
393+
{snackbarProperties.text}
339394
</Snackbar>
340395
</>
341396
);

src/components/Appbar/AppbarContent.tsx

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import {
66
StyleProp,
77
StyleSheet,
88
TextStyle,
9-
TouchableWithoutFeedback,
9+
Pressable,
1010
View,
1111
ViewStyle,
12+
ViewProps,
1213
} from 'react-native';
1314

1415
import color from 'color';
@@ -135,13 +136,15 @@ const AppbarContent = ({
135136

136137
const variant = modeTextVariant[mode] as MD3TypescaleKey;
137138

139+
const contentWrapperProps = {
140+
pointerEvents: 'box-none' as ViewProps['pointerEvents'],
141+
style: [styles.container, isV3 && modeContainerStyles[mode], style],
142+
testID,
143+
...rest,
144+
};
145+
138146
const content = (
139-
<View
140-
pointerEvents="box-none"
141-
style={[styles.container, isV3 && modeContainerStyles[mode], style]}
142-
testID={testID}
143-
{...rest}
144-
>
147+
<>
145148
{typeof title === 'string' ? (
146149
<Text
147150
{...(isV3 && { variant })}
@@ -185,26 +188,27 @@ const AppbarContent = ({
185188
{subtitle}
186189
</Text>
187190
) : null}
188-
</View>
191+
</>
189192
);
190193

191194
if (onPress) {
192195
return (
193196
// eslint-disable-next-line react-native-a11y/has-accessibility-props
194-
<TouchableWithoutFeedback
197+
<Pressable
195198
accessibilityRole={touchableRole}
196199
// @ts-expect-error We keep old a11y props for backwards compat with old RN versions
197200
accessibilityTraits={touchableRole}
198201
accessibilityComponentType="button"
199202
onPress={onPress}
200203
disabled={disabled}
204+
{...contentWrapperProps}
201205
>
202206
{content}
203-
</TouchableWithoutFeedback>
207+
</Pressable>
204208
);
205209
}
206210

207-
return content;
211+
return <View {...contentWrapperProps}>{content}</View>;
208212
};
209213

210214
AppbarContent.displayName = 'Appbar.Content';

src/components/BottomNavigation/BottomNavigation.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
Platform,
77
StyleProp,
88
StyleSheet,
9-
TouchableWithoutFeedbackProps,
109
View,
1110
ViewStyle,
1211
} from 'react-native';
@@ -19,6 +18,7 @@ import { useInternalTheme } from '../../core/theming';
1918
import type { ThemeProp } from '../../types';
2019
import useAnimatedValueArray from '../../utils/useAnimatedValueArray';
2120
import type { IconSource } from '../Icon';
21+
import { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple';
2222

2323
export type BaseRoute = {
2424
key: string;
@@ -42,7 +42,7 @@ type TabPressEvent = {
4242
preventDefault(): void;
4343
};
4444

45-
type TouchableProps<Route extends BaseRoute> = TouchableWithoutFeedbackProps & {
45+
type TouchableProps<Route extends BaseRoute> = TouchableRippleProps & {
4646
key: string;
4747
route: Route;
4848
children: React.ReactNode;
@@ -164,7 +164,7 @@ export type Props<Route extends BaseRoute> = {
164164
}) => React.ReactNode;
165165
/**
166166
* Callback which returns a React element to be used as the touchable for the tab item.
167-
* Renders a `TouchableRipple` on Android and `TouchableWithoutFeedback` with `View` on iOS.
167+
* Renders a `TouchableRipple` on Android and `Pressable` on iOS.
168168
*/
169169
renderTouchable?: (props: TouchableProps<Route>) => React.ReactNode;
170170
/**

src/components/BottomNavigation/BottomNavigationBar.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ import {
66
Platform,
77
StyleProp,
88
StyleSheet,
9-
TouchableWithoutFeedback,
10-
TouchableWithoutFeedbackProps,
9+
Pressable,
1110
View,
1211
ViewStyle,
1312
} from 'react-native';
@@ -32,6 +31,7 @@ import Badge from '../Badge';
3231
import Icon, { IconSource } from '../Icon';
3332
import Surface from '../Surface';
3433
import TouchableRipple from '../TouchableRipple/TouchableRipple';
34+
import { Props as TouchableRippleProps } from '../TouchableRipple/TouchableRipple';
3535
import Text from '../Typography/Text';
3636

3737
type BaseRoute = {
@@ -56,7 +56,7 @@ type TabPressEvent = {
5656
preventDefault(): void;
5757
};
5858

59-
type TouchableProps<Route extends BaseRoute> = TouchableWithoutFeedbackProps & {
59+
type TouchableProps<Route extends BaseRoute> = TouchableRippleProps & {
6060
key: string;
6161
route: Route;
6262
children: React.ReactNode;
@@ -134,7 +134,7 @@ export type Props<Route extends BaseRoute> = {
134134
}) => React.ReactNode;
135135
/**
136136
* Callback which returns a React element to be used as the touchable for the tab item.
137-
* Renders a `TouchableRipple` on Android and `TouchableWithoutFeedback` with `View` on iOS.
137+
* Renders a `TouchableRipple` on Android and `Pressable` on iOS.
138138
*/
139139
renderTouchable?: (props: TouchableProps<Route>) => React.ReactNode;
140140
/**
@@ -235,9 +235,9 @@ const Touchable = <Route extends BaseRoute>({
235235
{children}
236236
</TouchableRipple>
237237
) : (
238-
<TouchableWithoutFeedback {...rest}>
239-
<View style={style}>{children}</View>
240-
</TouchableWithoutFeedback>
238+
<Pressable style={style} {...rest}>
239+
{children}
240+
</Pressable>
241241
);
242242

243243
/**

src/components/Card/Card.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
GestureResponderEvent,
55
StyleProp,
66
StyleSheet,
7-
TouchableWithoutFeedback,
7+
Pressable,
88
View,
99
ViewStyle,
1010
} from 'react-native';
@@ -306,9 +306,9 @@ const Card = ({
306306
)}
307307

308308
{hasPassedTouchHandler ? (
309-
<TouchableWithoutFeedback
309+
<Pressable
310310
accessible={accessible}
311-
delayPressIn={0}
311+
unstable_pressDelay={0}
312312
disabled={disabled}
313313
delayLongPress={delayLongPress}
314314
onLongPress={onLongPress}
@@ -317,7 +317,7 @@ const Card = ({
317317
onPressOut={handlePressOut}
318318
>
319319
{content}
320-
</TouchableWithoutFeedback>
320+
</Pressable>
321321
) : (
322322
content
323323
)}

src/components/Chip/Chip.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
StyleProp,
99
StyleSheet,
1010
TextStyle,
11-
TouchableWithoutFeedback,
11+
Pressable,
1212
View,
1313
ViewStyle,
1414
} from 'react-native';
@@ -390,8 +390,9 @@ const Chip = ({
390390
</TouchableRipple>
391391
{onClose ? (
392392
<View style={styles.closeButtonStyle}>
393-
<TouchableWithoutFeedback
393+
<Pressable
394394
onPress={onClose}
395+
disabled={disabled}
395396
accessibilityRole="button"
396397
accessibilityLabel={closeIconAccessibilityLabel}
397398
>
@@ -413,7 +414,7 @@ const Chip = ({
413414
/>
414415
)}
415416
</View>
416-
</TouchableWithoutFeedback>
417+
</Pressable>
417418
</View>
418419
) : null}
419420
</Surface>

0 commit comments

Comments
 (0)