Skip to content

Commit 0aa3ee0

Browse files
Reanimated and GestureHandler upgrade (#3203)
* SectionsWheelPicker - wrap with GestureHandlerRootView * remove redundent * remove // @ts-expect-error should be fixed in version 3.5 (software-mansion/react-native-reanimated#4881) * Modal - applying useGestureHandlerRootView on iOS as well * TouchableOpacity - migrate from deprecated onGestureEvent to onHandleStateChange * PanView - migrate from PanGestureHandler with deprecated onGestureEvent to GestureDetector component with gesture * Calendar header - ignore TS error * upgrade libraries * gesture upgrade to 2.16.0 * gestureHandler to 2.14.1 * Modal - update docs * WheelPicker - wrap with GestureHandlerRootView, instead of wrapping the screen * Wrapping SectionWheelPickerScreen instead of WheelPicker component * clean * Remove migration from useAnimatedGestureHandler * //@ts-expect-error - useAnimatedGestureHandler migration * fix TS error on ConnectionStatusBar NetInfo.fetch * Revert "fix TS error on ConnectionStatusBar NetInfo.fetch" This reverts commit 323a558. * Revert "//@ts-expect-error - useAnimatedGestureHandler migration" This reverts commit 03a695c. * Revert "Remove migration from useAnimatedGestureHandler" This reverts commit 7957805. * Wrap screens with gestureHandlerRootHOC * Fix TabController's indicator * Fix PanView (and screen) * Remove missed comment * Change to map (also fixes initial indicator) --------- Co-authored-by: M-i-k-e-l <[email protected]>
1 parent 612c26c commit 0aa3ee0

File tree

20 files changed

+223
-107
lines changed

20 files changed

+223
-107
lines changed

demo/src/screens/componentScreens/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export function registerScreens(registrar) {
1515
registrar('unicorn.components.CheckboxScreen', () => require('./CheckboxScreen').default);
1616
registrar('unicorn.components.ChipScreen', () => require('./ChipScreen').default);
1717
registrar('unicorn.components.ChipsInputScreen', () => require('./ChipsInputScreen').default);
18-
registrar('unicorn.components.ColorPickerScreen', () => require('./ColorPickerScreen').default);
18+
registrar('unicorn.components.ColorPickerScreen', () => gestureHandlerRootHOC(require('./ColorPickerScreen').default));
1919
registrar('unicorn.components.ColorSwatchScreen', () => require('./ColorSwatchScreen').default);
2020
registrar('unicorn.components.ConnectionStatusBar', () => require('./ConnectionStatusBarScreen').default);
2121
registrar('unicorn.components.DateTimePickerScreen', () => require('./DateTimePickerScreen').default);
@@ -28,7 +28,7 @@ export function registerScreens(registrar) {
2828
registrar('unicorn.components.IconScreen', () => require('./IconScreen').default);
2929
registrar('unicorn.components.ImageScreen', () => require('./ImageScreen').default);
3030
registrar('unicorn.components.GridListScreen', () => require('./GridListScreen').default);
31-
registrar('unicorn.components.GridViewScreen', () => require('./GridViewScreen').default);
31+
registrar('unicorn.components.GridViewScreen', () => gestureHandlerRootHOC(require('./GridViewScreen').default));
3232
registrar('unicorn.components.KeyboardAwareScrollViewScreen', () => require('./KeyboardAwareScrollViewScreen').default);
3333
registrar('unicorn.components.MaskedInputScreen', () => require('./MaskedInputScreen').default);
3434
registrar('unicorn.components.MarqueeScreen', () => require('./MarqueeScreen').default);
@@ -38,12 +38,12 @@ export function registerScreens(registrar) {
3838
registrar('unicorn.components.PanDismissibleScreen', () => require('./PanDismissibleScreen').default);
3939
registrar('unicorn.components.PanListenerScreen', () => require('./PanListenerScreen').default);
4040
registrar('unicorn.components.PanResponderScreen', () => require('./PanResponderScreen').default);
41-
registrar('unicorn.components.PickerScreen', () => require('./PickerScreen').default);
41+
registrar('unicorn.components.PickerScreen', () => gestureHandlerRootHOC(require('./PickerScreen').default));
4242
registrar('unicorn.animations.ProgressBarScreen', () => require('../componentScreens/ProgressBarScreen').default);
4343
registrar('unicorn.components.ProgressiveImageScreen', () => require('./ProgressiveImageScreen').default);
4444
registrar('unicorn.components.RadioButtonScreen', () => require('./RadioButtonScreen').default);
4545
registrar('unicorn.components.ScrollBarScreen', () => require('./ScrollBarScreen').default);
46-
registrar('unicorn.components.SectionsWheelPickerScreen', () => require('./SectionsWheelPickerScreen').default);
46+
registrar('unicorn.components.SectionsWheelPickerScreen', () => gestureHandlerRootHOC(require('./SectionsWheelPickerScreen').default));
4747
registrar('unicorn.components.SegmentedControlScreen', () => require('./SegmentedControlScreen').default);
4848
registrar('unicorn.components.SharedTransitionScreen', () => require('./SharedTransitionScreen').default);
4949
registrar('unicorn.components.SkeletonViewScreen', () => require('./SkeletonViewScreen').default);

demo/src/screens/incubatorScreens/PanViewScreen.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,8 @@ class PanViewScreen extends Component {
146146

147147
render() {
148148
const {showToast, showDialog} = this.state;
149-
const Container = showDialog ? View : GestureHandlerRootView;
150149
return (
151-
<Container style={styles.root}>
150+
<GestureHandlerRootView style={styles.root}>
152151
<View marginL-page height={50} centerV>
153152
<Text text50>New Pan View</Text>
154153
</View>
@@ -164,7 +163,7 @@ class PanViewScreen extends Component {
164163
</ScrollView>
165164
{showToast && this.renderToast()}
166165
{showDialog && this.renderDialog()}
167-
</Container>
166+
</GestureHandlerRootView>
168167
);
169168
}
170169
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@
106106
"react-dom": "^18.2.0",
107107
"react-native": "0.71.12",
108108
"react-native-fs": "^2.20.0",
109-
"react-native-gesture-handler": "2.9.0",
109+
"react-native-gesture-handler": "2.14.1",
110110
"react-native-haptic-feedback": "^1.11.0",
111111
"react-native-linear-gradient": "2.6.2",
112112
"react-native-mmkv": "2.11.0",
113113
"react-native-navigation": "7.32.1",
114-
"react-native-reanimated": "3.4.0",
114+
"react-native-reanimated": "3.8.1",
115115
"react-native-shimmer-placeholder": "^2.0.6",
116116
"react-native-svg": "^13.7.0",
117117
"react-native-svg-transformer": "1.1.0",

src/components/marquee/index.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ function Marquee(props: MarqueeProps) {
7676
}
7777
}, [viewLayout, textLayout]);
7878

79-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
8079
const translateStyle = useAnimatedStyle(() => {
8180
if (offset.value) {
8281
return {
@@ -90,7 +89,6 @@ function Marquee(props: MarqueeProps) {
9089

9190
return (
9291
<View style={[styles.container, containerStyle]} onLayout={onLayoutView}>
93-
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
9492
<View reanimated style={[translateStyle]}>
9593
<Text style={[styles.text, labelStyle]} onLayout={onLayoutText}>
9694
{label}

src/components/modal/api/modal.api.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,7 @@
3333
{
3434
"name": "useGestureHandlerRootView",
3535
"type": "boolean",
36-
"description": "Should add a GestureHandlerRootView",
37-
"note": "Android only"
36+
"description": "Should add a GestureHandlerRootView"
3837
}
3938
],
4039
"snippet": [

src/components/modal/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export interface ModalProps extends RNModalProps {
4545
*/
4646
accessibilityLabel?: string;
4747
/**
48-
* Should add a GestureHandlerRootView (Android only)
48+
* Should add a GestureHandlerRootView
4949
*/
5050
useGestureHandlerRootView?: boolean;
5151
/**
@@ -112,9 +112,8 @@ class Modal extends Component<ModalProps> {
112112
...others
113113
} = this.props;
114114
const defaultContainer = enableModalBlur && Constants.isIOS && BlurView ? BlurView : View;
115-
const useGestureHandler = useGestureHandlerRootView && Constants.isAndroid;
116-
const GestureContainer = useGestureHandler ? GestureHandlerRootView : React.Fragment;
117-
const gestureContainerProps = useGestureHandler ? {style: styles.fill} : {};
115+
const GestureContainer = useGestureHandlerRootView ? GestureHandlerRootView : React.Fragment;
116+
const gestureContainerProps = useGestureHandlerRootView ? {style: styles.fill} : {};
118117
const useKeyboardAvoiding = useKeyboardAvoidingView && Constants.isIOS;
119118
const KeyboardAvoidingContainer = useKeyboardAvoiding ? KeyboardAvoidingView : React.Fragment;
120119
const keyboardAvoidingContainerProps = useKeyboardAvoiding

src/components/sortableGridList/SortableItem.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ function SortableItem(props: PropsWithChildren<SortableItemProps & ReturnType<ty
171171
}
172172
});
173173

174-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
175174
const animatedStyle = useAnimatedStyle(() => {
176175
const scale = withSpring(isDragging.value ? 1.1 : 1);
177176
const zIndex = isDragging.value ? 100 : withTiming(0, animationConfig);
@@ -183,7 +182,6 @@ function SortableItem(props: PropsWithChildren<SortableItemProps & ReturnType<ty
183182
});
184183

185184
return (
186-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
187185
<View reanimated style={[style, animatedStyle]} onLayout={onLayout}>
188186
<GestureDetector gesture={dragOnLongPressGesture}>
189187
<View>{props.children}</View>

src/components/tabController/PageCarousel.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ function PageCarousel(props: ScrollViewProps) {
104104
<Reanimated.ScrollView
105105
{...others}
106106
style={_style}
107-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
108107
ref={carousel}
109108
horizontal
110109
pagingEnabled

src/components/tabController/TabBarItem.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ export interface TabControllerItemProps extends Pick<TabControllerBarProps, 'spr
105105
interface Props extends TabControllerItemProps {
106106
index: number;
107107
targetPage: any; // TODO: typescript?
108-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
109108
currentPage: Reanimated.Adaptable<number>;
110109
onLayout?: (event: LayoutChangeEvent, index: number) => void;
111110
}

src/components/tabController/useScrollToItem.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,6 @@ const useScrollToItem = <T extends ScrollToSupportedViews>(props: ScrollToItemPr
128128
const rightOffsets = [];
129129
rightOffsets.push(-containerWidth + widths[0] + outerSpacing + innerSpacing);
130130
while (index < itemsCount) {
131-
/* map animated widths and offsets */
132-
itemsWidthsAnimated.value[index] = widths[index];
133-
if (index > 0) {
134-
itemsOffsetsAnimated.value[index] =
135-
itemsOffsetsAnimated.value[index - 1] + itemsWidthsAnimated.value[index - 1];
136-
}
137-
138131
/* calc center, left and right offsets */
139132
centeredOffsets[index] = currentCenterOffset - screenCenter + widths[index] / 2;
140133
++index;
@@ -154,9 +147,24 @@ const useScrollToItem = <T extends ScrollToSupportedViews>(props: ScrollToItemPr
154147

155148
setOffsets({CENTER: centeredOffsets, LEFT: leftOffsets, RIGHT: rightOffsets}); // default for DYNAMIC is CENTER
156149

157-
// trigger value change
158-
itemsWidthsAnimated.value = [...itemsWidthsAnimated.value];
159-
itemsOffsetsAnimated.value = [...itemsOffsetsAnimated.value];
150+
// Update shared values
151+
itemsWidthsAnimated.modify((value) => {
152+
'worklet';
153+
value.forEach((_, index) => {
154+
value[index] = widths[index];
155+
});
156+
return value;
157+
});
158+
159+
itemsOffsetsAnimated.modify((value) => {
160+
'worklet';
161+
value.forEach((_, index) => {
162+
if (index > 0) {
163+
value[index] = value[index - 1] + widths[index - 1];
164+
}
165+
});
166+
return value;
167+
});
160168
},
161169
[itemsCount, outerSpacing, innerSpacing, addOffsetMargin, containerWidth]);
162170

src/components/textField/ClearButton.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const ClearButton = ({testID, onClear, onChangeText}: Pick<TextFieldProps, 'onCl
2222
const animatedValue = useSharedValue(hasValue ? VISIBLE_POSITION : NON_VISIBLE_POSITION);
2323
const animatedOpacity = useSharedValue(hasValue ? 1 : 0);
2424

25-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
2625
const animatedStyle = useAnimatedStyle(() => {
2726
return {
2827
transform: [{translateY: animatedValue.value}, {translateX: 0}],
@@ -49,7 +48,6 @@ const ClearButton = ({testID, onClear, onChangeText}: Pick<TextFieldProps, 'onCl
4948
};
5049

5150
return (
52-
//@ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
5351
<View reanimated style={style} testID={`${testID}.container`}>
5452
<Button
5553
link

src/incubator/Calendar/Header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ const Header = (props: HeaderProps) => {
5858
return <Text style={styles.title}>{title}</Text>;
5959
}
6060
return (
61+
//@ts-expect-error - hack to animate the title text change
6162
<AnimatedTextInput
6263
value={getTitle(selectedDate.value)} // setting initial value
6364
{...{animatedProps}}
6465
editable={false}
65-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
6666
style={styles.title}
6767
/>);
6868
};

src/incubator/Calendar/TodayButton.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const TodayButton = (props: TodayButtonProps) => {
1616
const {containerStyle, buttonProps} = props;
1717
const {selectedDate, setDate} = useContext(CalendarContext);
1818

19-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
2019
const animatedStyle = useAnimatedStyle(() => {
2120
return {
2221
transform: [
@@ -40,7 +39,6 @@ const TodayButton = (props: TodayButtonProps) => {
4039
[buttonProps]);
4140

4241
return (
43-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
4442
<View reanimated style={[styles.container, containerStyle, animatedStyle]}>
4543
<Button
4644
outline

src/incubator/Dialog/index.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
137137
children
138138
});
139139

140-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
141140
const animatedStyle = useAnimatedStyle(() => {
142141
if (isVertical) {
143142
return {
@@ -213,7 +212,6 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
213212

214213
const renderDialog = () => (
215214
<GestureDetector gesture={panGesture}>
216-
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
217215
<View {...containerProps} reanimated style={style} onLayout={onLayout} ref={setRef} testID={testID}>
218216
{renderDialogContent()}
219217
</View>

src/incubator/Slider/Thumb.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ const Thumb = (props: ThumbProps) => {
8787
});
8888
gesture.enabled(!disabled);
8989

90-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
9190
const animatedStyle = useAnimatedStyle(() => {
9291
const customStyle = isPressed.value ? activeStyle?.value : defaultStyle?.value;
9392
return {
@@ -110,7 +109,6 @@ const Thumb = (props: ThumbProps) => {
110109
<GestureDetector gesture={gesture}>
111110
<View
112111
reanimated
113-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
114112
style={[styles.thumbPosition, enableShadow && styles.thumbShadow, animatedStyle]}
115113
hitSlop={hitSlop}
116114
onLayout={onThumbLayout}

src/incubator/Slider/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,6 @@ const Slider = React.memo((props: Props) => {
373373
}
374374
};
375375

376-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
377376
const trackAnimatedStyles = useAnimatedStyle(() => {
378377
if (useRange) {
379378
return {

src/incubator/TouchableOpacity.tsx

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, {PropsWithChildren, useCallback, useMemo} from 'react';
22
import {LayoutChangeEvent} from 'react-native';
33
import Reanimated, {
4-
useAnimatedGestureHandler,
54
useAnimatedStyle,
65
useSharedValue,
76
withTiming,
@@ -104,35 +103,41 @@ function TouchableOpacity(props: Props) {
104103
isActive.value = withTiming(value, {duration: 200});
105104
};
106105

107-
const tapGestureHandler = useAnimatedGestureHandler({
108-
onStart: () => {
109-
toggleActive(1);
110-
},
111-
onEnd: () => {
112-
toggleActive(0);
113-
runOnJS(onPress)();
114-
},
115-
onFail: () => {
116-
if (!isLongPressed.value) {
106+
const tapGestureHandler = ({nativeEvent: {state}}: any) => {
107+
switch (state) {
108+
case State.BEGAN:
109+
toggleActive(1);
110+
break;
111+
case State.CANCELLED:
112+
case State.END:
117113
toggleActive(0);
118-
}
114+
runOnJS(onPress)();
115+
break;
116+
case State.FAILED:
117+
if (!isLongPressed.value) {
118+
toggleActive(0);
119+
}
120+
break;
119121
}
120-
});
121-
122-
const longPressGestureHandler = useAnimatedGestureHandler({
123-
onActive: () => {
124-
if (!isLongPressed.value) {
125-
isLongPressed.value = true;
126-
runOnJS(onLongPress)();
127-
}
128-
},
129-
onFinish: () => {
130-
toggleActive(0);
131-
isLongPressed.value = false;
122+
};
123+
124+
const longPressGestureHandler = ({nativeEvent: {state}}: any) => {
125+
switch (state) {
126+
case State.ACTIVE:
127+
if (!isLongPressed.value) {
128+
isLongPressed.value = true;
129+
runOnJS(onLongPress)();
130+
}
131+
break;
132+
case State.CANCELLED:
133+
case State.END:
134+
case State.FAILED:
135+
toggleActive(0);
136+
isLongPressed.value = false;
137+
break;
132138
}
133-
});
139+
};
134140

135-
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
136141
const animatedStyle = useAnimatedStyle(() => {
137142
const activeColor = feedbackColor || backgroundColor;
138143
const opacity = interpolate(isActive.value, [0, 1], [1, activeOpacity]);
@@ -151,12 +156,12 @@ function TouchableOpacity(props: Props) {
151156

152157
return (
153158
<TapGestureHandler
154-
onGestureEvent={tapGestureHandler}
159+
onHandlerStateChange={tapGestureHandler}
155160
shouldCancelWhenOutside
156161
enabled={!disabled}
157162
>
158163
<Reanimated.View>
159-
<Container onGestureEvent={longPressGestureHandler} shouldCancelWhenOutside>
164+
<Container onHandlerStateChange={longPressGestureHandler} shouldCancelWhenOutside>
160165
<Reanimated.View
161166
{...others}
162167
ref={forwardedRef}

0 commit comments

Comments
 (0)