diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.tsx b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.tsx index efd143c9487c..0ca7756b0e0e 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/index.native.tsx +++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.native.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {Animated} from 'react-native'; +import Animated, {useAnimatedStyle} from 'react-native-reanimated'; import useSafeAreaInsets from '@hooks/useSafeAreaInsets'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -9,8 +9,9 @@ function GrowlNotificationContainer({children, translateY}: GrowlNotificationCon const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const insets = useSafeAreaInsets(); + const animatedStyles = useAnimatedStyle(() => styles.growlNotificationTranslateY(translateY)); - return {children}; + return {children}; } GrowlNotificationContainer.displayName = 'GrowlNotificationContainer'; diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/index.tsx b/src/components/GrowlNotification/GrowlNotificationContainer/index.tsx index 78d80bbb36b6..f1113029bc86 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/index.tsx +++ b/src/components/GrowlNotification/GrowlNotificationContainer/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import {Animated} from 'react-native'; +import Animated, {useAnimatedStyle} from 'react-native-reanimated'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useThemeStyles from '@hooks/useThemeStyles'; import type GrowlNotificationContainerProps from './types'; @@ -7,13 +7,10 @@ import type GrowlNotificationContainerProps from './types'; function GrowlNotificationContainer({children, translateY}: GrowlNotificationContainerProps) { const styles = useThemeStyles(); const {shouldUseNarrowLayout} = useResponsiveLayout(); + const animatedStyles = useAnimatedStyle(() => styles.growlNotificationTranslateY(translateY)); return ( - - {children} - + {children} ); } diff --git a/src/components/GrowlNotification/GrowlNotificationContainer/types.ts b/src/components/GrowlNotification/GrowlNotificationContainer/types.ts index 91a48437dbd9..5f137f6d3c48 100644 --- a/src/components/GrowlNotification/GrowlNotificationContainer/types.ts +++ b/src/components/GrowlNotification/GrowlNotificationContainer/types.ts @@ -1,8 +1,8 @@ -import type {Animated} from 'react-native'; +import type {SharedValue} from 'react-native-reanimated'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; type GrowlNotificationContainerProps = ChildrenProps & { - translateY: Animated.Value; + translateY: SharedValue; }; export default GrowlNotificationContainerProps; diff --git a/src/components/GrowlNotification/index.tsx b/src/components/GrowlNotification/index.tsx index d0846dcf7a42..14cad991f096 100644 --- a/src/components/GrowlNotification/index.tsx +++ b/src/components/GrowlNotification/index.tsx @@ -1,7 +1,8 @@ import type {ForwardedRef} from 'react'; -import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react'; -import {Animated, View} from 'react-native'; +import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useState} from 'react'; +import {View} from 'react-native'; import {Directions, Gesture, GestureDetector} from 'react-native-gesture-handler'; +import {useSharedValue, withSpring} from 'react-native-reanimated'; import type {SvgProps} from 'react-native-svg'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -11,7 +12,6 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as Growl from '@libs/Growl'; import type {GrowlRef} from '@libs/Growl'; -import useNativeDriver from '@libs/useNativeDriver'; import CONST from '@src/CONST'; import GrowlNotificationContainer from './GrowlNotificationContainer'; @@ -20,7 +20,7 @@ const INACTIVE_POSITION_Y = -255; const PressableWithoutFeedback = Pressables.PressableWithoutFeedback; function GrowlNotification(_: unknown, ref: ForwardedRef) { - const translateY = useRef(new Animated.Value(INACTIVE_POSITION_Y)).current; + const translateY = useSharedValue(INACTIVE_POSITION_Y); const [bodyText, setBodyText] = useState(''); const [type, setType] = useState('success'); const [duration, setDuration] = useState(); @@ -76,10 +76,9 @@ function GrowlNotification(_: unknown, ref: ForwardedRef) { */ const fling = useCallback( (val = INACTIVE_POSITION_Y) => { - Animated.spring(translateY, { - toValue: val, - useNativeDriver, - }).start(); + translateY.value = withSpring(val, { + overshootClamping: false, + }); }, [translateY], ); diff --git a/src/styles/index.ts b/src/styles/index.ts index b17376ecf0e0..b658739201b7 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -6,6 +6,7 @@ import type {AnimatableNumericValue, Animated, ImageStyle, TextStyle, ViewStyle} import {Platform, StyleSheet} from 'react-native'; import type {CustomAnimation} from 'react-native-animatable'; import type {PickerStyle} from 'react-native-picker-select'; +import type {SharedValue} from 'react-native-reanimated'; import type {MixedStyleDeclaration, MixedStyleRecord} from 'react-native-render-html'; import type {ValueOf} from 'type-fest'; import type DotLottieAnimation from '@components/LottieAnimations/types'; @@ -3343,10 +3344,9 @@ const styles = (theme: ThemeColors) => ...positioning.pFixed, }, - growlNotificationTranslateY: (translateY: AnimatableNumericValue) => - ({ - transform: [{translateY}], - } satisfies ViewStyle), + growlNotificationTranslateY: (translateY: SharedValue) => ({ + transform: [{translateY: translateY.value}], + }), makeSlideInTranslation: (translationType: Translation, fromValue: number) => ({