Skip to content

Reanimated and GestureHandler upgrade #3203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Sep 1, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8f76e95
SectionsWheelPicker - wrap with GestureHandlerRootView
Inbal-Tish Aug 7, 2024
1b1c725
remove redundent
Inbal-Tish Aug 7, 2024
adcaf4a
remove // @ts-expect-error should be fixed in version 3.5 (https://gi…
Inbal-Tish Aug 7, 2024
e8f970c
Modal - applying useGestureHandlerRootView on iOS as well
Inbal-Tish Aug 8, 2024
66e0b0c
TouchableOpacity - migrate from deprecated onGestureEvent to onHandle…
Inbal-Tish Aug 8, 2024
88ef194
PanView - migrate from PanGestureHandler with deprecated onGestureEve…
Inbal-Tish Aug 8, 2024
c501fc4
Calendar header - ignore TS error
Inbal-Tish Aug 8, 2024
97a0973
upgrade libraries
Inbal-Tish Aug 8, 2024
c54cafe
gesture upgrade to 2.16.0
Inbal-Tish Aug 11, 2024
28b750a
gestureHandler to 2.14.1
Inbal-Tish Aug 13, 2024
70d2a05
Modal - update docs
Inbal-Tish Aug 13, 2024
418fbd2
WheelPicker - wrap with GestureHandlerRootView, instead of wrapping t…
Inbal-Tish Aug 13, 2024
36ec4a6
Wrapping SectionWheelPickerScreen instead of WheelPicker component
Inbal-Tish Aug 13, 2024
8324ef9
clean
Inbal-Tish Aug 13, 2024
7957805
Remove migration from useAnimatedGestureHandler
Inbal-Tish Aug 14, 2024
03a695c
//@ts-expect-error - useAnimatedGestureHandler migration
Inbal-Tish Aug 14, 2024
323a558
fix TS error on ConnectionStatusBar NetInfo.fetch
Inbal-Tish Aug 15, 2024
6a545d4
Revert "fix TS error on ConnectionStatusBar NetInfo.fetch"
Inbal-Tish Aug 15, 2024
98d62a3
Revert "//@ts-expect-error - useAnimatedGestureHandler migration"
Inbal-Tish Aug 15, 2024
c616f07
Revert "Remove migration from useAnimatedGestureHandler"
Inbal-Tish Aug 15, 2024
3c6c796
Wrap screens with gestureHandlerRootHOC
Inbal-Tish Aug 15, 2024
a3bcdc7
Merge branch 'master' into fix/GestureHandlerRootView
M-i-k-e-l Aug 18, 2024
df8f1b8
Fix TabController's indicator
M-i-k-e-l Aug 19, 2024
ae5b10f
Fix PanView (and screen)
M-i-k-e-l Aug 19, 2024
167c3b6
Remove missed comment
M-i-k-e-l Aug 19, 2024
a07caac
Change to map (also fixes initial indicator)
M-i-k-e-l Aug 27, 2024
1e21608
Revert "Change to map (also fixes initial indicator)"
M-i-k-e-l Sep 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion demo/src/screens/componentScreens/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function registerScreens(registrar) {
registrar('unicorn.components.ProgressiveImageScreen', () => require('./ProgressiveImageScreen').default);
registrar('unicorn.components.RadioButtonScreen', () => require('./RadioButtonScreen').default);
registrar('unicorn.components.ScrollBarScreen', () => require('./ScrollBarScreen').default);
registrar('unicorn.components.SectionsWheelPickerScreen', () => require('./SectionsWheelPickerScreen').default);
registrar('unicorn.components.SectionsWheelPickerScreen', () => gestureHandlerRootHOC(require('./SectionsWheelPickerScreen').default));
registrar('unicorn.components.SegmentedControlScreen', () => require('./SegmentedControlScreen').default);
registrar('unicorn.components.SharedTransitionScreen', () => require('./SharedTransitionScreen').default);
registrar('unicorn.components.SkeletonViewScreen', () => require('./SkeletonViewScreen').default);
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@
"react-dom": "^18.2.0",
"react-native": "0.71.12",
"react-native-fs": "^2.20.0",
"react-native-gesture-handler": "2.9.0",
"react-native-gesture-handler": "2.14.1",
"react-native-haptic-feedback": "^1.11.0",
"react-native-linear-gradient": "2.6.2",
"react-native-mmkv": "2.11.0",
"react-native-navigation": "7.32.1",
"react-native-reanimated": "3.4.0",
"react-native-reanimated": "3.8.1",
"react-native-shimmer-placeholder": "^2.0.6",
"react-native-svg": "^13.7.0",
"react-native-svg-transformer": "1.1.0",
Expand Down
2 changes: 0 additions & 2 deletions src/components/marquee/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ function Marquee(props: MarqueeProps) {
}
}, [viewLayout, textLayout]);

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

return (
<View style={[styles.container, containerStyle]} onLayout={onLayoutView}>
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
<View reanimated style={[translateStyle]}>
<Text style={[styles.text, labelStyle]} onLayout={onLayoutText}>
{label}
Expand Down
3 changes: 1 addition & 2 deletions src/components/modal/api/modal.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
{
"name": "useGestureHandlerRootView",
"type": "boolean",
"description": "Should add a GestureHandlerRootView",
"note": "Android only"
"description": "Should add a GestureHandlerRootView"
}
],
"snippet": [
Expand Down
7 changes: 3 additions & 4 deletions src/components/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface ModalProps extends RNModalProps {
*/
accessibilityLabel?: string;
/**
* Should add a GestureHandlerRootView (Android only)
* Should add a GestureHandlerRootView
*/
useGestureHandlerRootView?: boolean;
/**
Expand Down Expand Up @@ -112,9 +112,8 @@ class Modal extends Component<ModalProps> {
...others
} = this.props;
const defaultContainer = enableModalBlur && Constants.isIOS && BlurView ? BlurView : View;
const useGestureHandler = useGestureHandlerRootView && Constants.isAndroid;
const GestureContainer = useGestureHandler ? GestureHandlerRootView : React.Fragment;
const gestureContainerProps = useGestureHandler ? {style: styles.fill} : {};
const GestureContainer = useGestureHandlerRootView ? GestureHandlerRootView : React.Fragment;
const gestureContainerProps = useGestureHandlerRootView ? {style: styles.fill} : {};
const useKeyboardAvoiding = useKeyboardAvoidingView && Constants.isIOS;
const KeyboardAvoidingContainer = useKeyboardAvoiding ? KeyboardAvoidingView : React.Fragment;
const keyboardAvoidingContainerProps = useKeyboardAvoiding
Expand Down
2 changes: 0 additions & 2 deletions src/components/sortableGridList/SortableItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ function SortableItem(props: PropsWithChildren<SortableItemProps & ReturnType<ty
}
});

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

return (
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
<View reanimated style={[style, animatedStyle]} onLayout={onLayout}>
<GestureDetector gesture={dragOnLongPressGesture}>
<View>{props.children}</View>
Expand Down
1 change: 0 additions & 1 deletion src/components/tabController/PageCarousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ function PageCarousel(props: ScrollViewProps) {
<Reanimated.ScrollView
{...others}
style={_style}
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
ref={carousel}
horizontal
pagingEnabled
Expand Down
1 change: 0 additions & 1 deletion src/components/tabController/TabBarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ export interface TabControllerItemProps extends Pick<TabControllerBarProps, 'spr
interface Props extends TabControllerItemProps {
index: number;
targetPage: any; // TODO: typescript?
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
currentPage: Reanimated.Adaptable<number>;
onLayout?: (event: LayoutChangeEvent, index: number) => void;
}
Expand Down
2 changes: 0 additions & 2 deletions src/components/textField/ClearButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const ClearButton = ({testID, onClear, onChangeText}: Pick<TextFieldProps, 'onCl
const animatedValue = useSharedValue(hasValue ? VISIBLE_POSITION : NON_VISIBLE_POSITION);
const animatedOpacity = useSharedValue(hasValue ? 1 : 0);

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

return (
//@ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
<View reanimated style={style} testID={`${testID}.container`}>
<Button
link
Expand Down
2 changes: 1 addition & 1 deletion src/incubator/Calendar/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ const Header = (props: HeaderProps) => {
return <Text style={styles.title}>{title}</Text>;
}
return (
//@ts-expect-error - hack to animate the title text change
<AnimatedTextInput
value={getTitle(selectedDate.value)} // setting initial value
{...{animatedProps}}
editable={false}
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
style={styles.title}
/>);
};
Expand Down
2 changes: 0 additions & 2 deletions src/incubator/Calendar/TodayButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const TodayButton = (props: TodayButtonProps) => {
const {containerStyle, buttonProps} = props;
const {selectedDate, setDate} = useContext(CalendarContext);

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

return (
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
<View reanimated style={[styles.container, containerStyle, animatedStyle]}>
<Button
outline
Expand Down
2 changes: 0 additions & 2 deletions src/incubator/Dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
const animatedStyle = useAnimatedStyle(() => {
if (isVertical) {
return {
Expand Down Expand Up @@ -200,7 +199,6 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)

const renderDialog = () => (
<GestureDetector gesture={panGesture}>
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
<View {...containerProps} reanimated style={style} onLayout={onLayout} ref={setRef} testID={testID}>
{headerProps && <DialogHeader {...headerProps}/>}
{children}
Expand Down
2 changes: 0 additions & 2 deletions src/incubator/Slider/Thumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ const Thumb = (props: ThumbProps) => {
});
gesture.enabled(!disabled);

// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
const animatedStyle = useAnimatedStyle(() => {
const customStyle = isPressed.value ? activeStyle?.value : defaultStyle?.value;
return {
Expand All @@ -110,7 +109,6 @@ const Thumb = (props: ThumbProps) => {
<GestureDetector gesture={gesture}>
<View
reanimated
// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
style={[styles.thumbPosition, enableShadow && styles.thumbShadow, animatedStyle]}
hitSlop={hitSlop}
onLayout={onThumbLayout}
Expand Down
1 change: 0 additions & 1 deletion src/incubator/Slider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ const Slider = React.memo((props: Props) => {
}
};

// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
const trackAnimatedStyles = useAnimatedStyle(() => {
if (useRange) {
return {
Expand Down
61 changes: 33 additions & 28 deletions src/incubator/TouchableOpacity.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, {PropsWithChildren, useCallback, useMemo} from 'react';
import {LayoutChangeEvent} from 'react-native';
import Reanimated, {
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
withTiming,
Expand Down Expand Up @@ -104,35 +103,41 @@ function TouchableOpacity(props: Props) {
isActive.value = withTiming(value, {duration: 200});
};

const tapGestureHandler = useAnimatedGestureHandler({
onStart: () => {
toggleActive(1);
},
onEnd: () => {
toggleActive(0);
runOnJS(onPress)();
},
onFail: () => {
if (!isLongPressed.value) {
const tapGestureHandler = ({nativeEvent: {state}}: any) => {
switch (state) {
case State.BEGAN:
toggleActive(1);
break;
case State.CANCELLED:
case State.END:
toggleActive(0);
}
runOnJS(onPress)();
break;
case State.FAILED:
if (!isLongPressed.value) {
toggleActive(0);
}
break;
}
});

const longPressGestureHandler = useAnimatedGestureHandler({
onActive: () => {
if (!isLongPressed.value) {
isLongPressed.value = true;
runOnJS(onLongPress)();
}
},
onFinish: () => {
toggleActive(0);
isLongPressed.value = false;
};

const longPressGestureHandler = ({nativeEvent: {state}}: any) => {
switch (state) {
case State.ACTIVE:
if (!isLongPressed.value) {
isLongPressed.value = true;
runOnJS(onLongPress)();
}
break;
case State.CANCELLED:
case State.END:
case State.FAILED:
toggleActive(0);
isLongPressed.value = false;
break;
}
});
};

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

return (
<TapGestureHandler
onGestureEvent={tapGestureHandler}
onHandlerStateChange={tapGestureHandler}
shouldCancelWhenOutside
enabled={!disabled}
>
<Reanimated.View>
<Container onGestureEvent={longPressGestureHandler} shouldCancelWhenOutside>
<Container onHandlerStateChange={longPressGestureHandler} shouldCancelWhenOutside>
<Reanimated.View
{...others}
ref={forwardedRef}
Expand Down
14 changes: 6 additions & 8 deletions src/incubator/panView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import {isEmpty} from 'lodash';
import React from 'react';
import {StyleProp, View as RNView, ViewStyle} from 'react-native';
import {useAnimatedStyle} from 'react-native-reanimated';
import {PanGestureHandler} from 'react-native-gesture-handler';
import {GestureDetector} from 'react-native-gesture-handler';
import {asBaseComponent} from '../../commons/new';
import View, {ViewProps} from '../../components/view';
import {PanningDirections, PanningDirectionsEnum} from './panningUtil';
import useHiddenLocation from '../hooks/useHiddenLocation';
import {PanningDirections, PanningDirectionsEnum} from './panningUtil';
import usePanGesture, {
PanGestureProps,
PanViewDirections,
Expand All @@ -15,6 +14,7 @@ import usePanGesture, {
DEFAULT_DIRECTIONS,
DEFAULT_ANIMATION_CONFIG
} from './usePanGesture';

export {
PanningDirections,
PanningDirectionsEnum,
Expand Down Expand Up @@ -50,7 +50,7 @@ const PanView = (props: Props) => {
} = props;

const {setRef, onLayout, hiddenLocation} = useHiddenLocation<RNView>();
const {translation, panGestureEvent} = usePanGesture({
const {translation, gesture} = usePanGesture({
directions,
dismissible,
animateToOrigin,
Expand All @@ -60,7 +60,6 @@ const PanView = (props: Props) => {
hiddenLocation
});

// @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881)
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{translateX: translation.x.value}, {translateY: translation.y.value}]
Expand All @@ -69,12 +68,11 @@ const PanView = (props: Props) => {

return (
<View ref={setRef} style={containerStyle} onLayout={onLayout}>
<PanGestureHandler onGestureEvent={isEmpty(directions) ? undefined : panGestureEvent}>
{/* @ts-expect-error should be fixed in version 3.5 (https://github.com/software-mansion/react-native-reanimated/pull/4881) */}
<GestureDetector gesture={gesture}>
<View reanimated style={animatedStyle}>
<View {...others}>{children}</View>
</View>
</PanGestureHandler>
</GestureDetector>
</View>
);
};
Expand Down
27 changes: 13 additions & 14 deletions src/incubator/panView/usePanGesture.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {useCallback} from 'react';
import {PanGestureHandlerEventPayload} from 'react-native-gesture-handler';
import {useSharedValue, withSpring, withTiming, useAnimatedGestureHandler, runOnJS} from 'react-native-reanimated';
import {useSharedValue, withSpring, withTiming, runOnJS} from 'react-native-reanimated';
import {PanGestureHandlerEventPayload, Gesture} from 'react-native-gesture-handler';
import {
PanningDirections,
PanningDirectionsEnum,
Expand Down Expand Up @@ -69,6 +69,7 @@ const usePanGesture = (props: PanGestureProps) => {
const waitingForDismiss = useSharedValue<boolean>(false);
const translationX = useSharedValue<number>(0);
const translationY = useSharedValue<number>(0);
const initialTranslation = useSharedValue<Frame>({x: 0, y: 0});

const getTranslationOptions = () => {
'worklet';
Expand Down Expand Up @@ -112,14 +113,14 @@ const usePanGesture = (props: PanGestureProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [animateToOrigin]);

const onGestureEvent = useAnimatedGestureHandler({
onStart: (_event: PanGestureHandlerEventPayload, context: {initialTranslation: Frame}) => {
context.initialTranslation = {x: translationX.value, y: translationY.value};
},
onActive: (event: PanGestureHandlerEventPayload, context: {initialTranslation: Frame}) => {
setTranslation(event, context.initialTranslation);
},
onEnd: (event: PanGestureHandlerEventPayload) => {
const panGesture = Gesture.Pan()
.onBegin(() => {
initialTranslation.value = {x: translationX.value, y: translationY.value};
})
.onStart((event: PanGestureHandlerEventPayload) => {
setTranslation(event, initialTranslation.value);
})
.onEnd((event: PanGestureHandlerEventPayload) => {
if (dismissible) {
const velocity = getDismissVelocity(event, directions, getTranslationOptions(), threshold);
if (velocity) {
Expand All @@ -141,11 +142,9 @@ const usePanGesture = (props: PanGestureProps) => {
} else {
returnToOrigin();
}
}
},
[directions, dismissible, setTranslation, returnToOrigin]);
});

return {translation: {x: translationX, y: translationY}, panGestureEvent: onGestureEvent, reset};
return {translation: {x: translationX, y: translationY}, gesture: panGesture, reset};
};

export default usePanGesture;
Loading