@momo-kits/foundation 0.161.2-beta.6 → 0.161.2-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,7 @@
1
- import React, { Ref, useContext } from 'react';
1
+ import React, { Ref, useContext, useEffect, useRef } from 'react';
2
2
  import LinearGradient from 'react-native-linear-gradient';
3
- import { Dimensions, Platform, StyleSheet, View } from 'react-native';
4
- import Animated, {
5
- Extrapolation,
6
- interpolate,
7
- useAnimatedStyle,
8
- useSharedValue,
9
- type SharedValue,
10
- } from 'react-native-reanimated';
11
3
  import { ApplicationContext, MiniAppContext } from '../../Context';
4
+ import { Animated, Dimensions, Platform, StyleSheet, View } from 'react-native';
12
5
  import { HeaderType } from '../../Layout/types';
13
6
  import { InputRef, InputSearch } from '../../Input';
14
7
  import Navigation from '../Navigation';
@@ -21,10 +14,15 @@ const SCREEN_PADDING = 12;
21
14
  const BACK_WIDTH = 28;
22
15
 
23
16
  const { width: screenWidth } = Dimensions.get('window');
17
+ const LinearGradientAnimated = Animated.createAnimatedComponent(LinearGradient);
24
18
 
19
+ /**
20
+ * Header extended with background image
21
+ * @constructor
22
+ */
25
23
  const HeaderExtendHeader: React.FC<{
26
24
  headerType?: HeaderType;
27
- animatedValue: SharedValue<number>;
25
+ animatedValue: Animated.Value;
28
26
  heightHeader: number;
29
27
  headerRightWidth: number;
30
28
  inputSearchProps?: SearchHeaderProps;
@@ -40,132 +38,118 @@ const HeaderExtendHeader: React.FC<{
40
38
  headerRightWidth = 73,
41
39
  inputSearchProps,
42
40
  inputSearchRef,
43
- useShadowHeader: useShadowHeaderProp = true,
41
+ useShadowHeader = true,
44
42
  gradientColor: customGradientColor,
45
43
  headerBackground: customBackground,
46
44
  }) => {
47
45
  const { theme } = useContext(ApplicationContext);
48
46
  const context = useContext<any>(MiniAppContext);
49
- const fallback = useSharedValue(0);
50
- const sv = animatedValue ?? fallback;
47
+ const animated = useRef(new Animated.Value(0));
51
48
  const gradientColor = customGradientColor ?? theme.colors.gradient;
52
49
  const headerBackground = customBackground ?? theme.assets?.headerBackground;
53
50
  const leftPosition = inputSearchProps?.leftPosition || BACK_WIDTH + 20;
54
51
 
55
- let useShadowHeader = useShadowHeaderProp;
56
- if (inputSearchProps && Platform.OS === 'android') {
57
- useShadowHeader = false;
58
- }
59
-
60
52
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
61
53
 
62
- const heightStyle = useAnimatedStyle(() => ({
63
- height: interpolate(
64
- sv.value,
65
- [0, 100],
66
- [heightHeader + 52, heightHeader],
67
- Extrapolation.CLAMP,
68
- ),
69
- }));
54
+ const opacityBackground = animatedValue?.interpolate({
55
+ inputRange: [0, 52],
56
+ outputRange: [0, 1],
57
+ extrapolate: 'clamp',
58
+ });
59
+ const opacityGradient = animatedValue?.interpolate({
60
+ inputRange: [0, 52],
61
+ outputRange: [1, 0],
62
+ extrapolate: 'clamp',
63
+ });
70
64
 
71
- const gradientOpacityStyle = useAnimatedStyle(() => ({
72
- opacity: interpolate(sv.value, [0, 52], [1, 0], Extrapolation.CLAMP),
73
- }));
65
+ useEffect(() => {
66
+ const listener = animatedValue.addListener(({ value }) => {
67
+ animated.current.setValue(value);
68
+ });
69
+ return () => {
70
+ animatedValue?.removeListener(listener);
71
+ };
72
+ }, [animatedValue]);
74
73
 
75
- const searchTranslateStyle = useAnimatedStyle(() => ({
76
- transform: [
77
- {
78
- translateX: interpolate(
79
- sv.value,
80
- [0, 100],
81
- [SCREEN_PADDING, leftPosition],
82
- Extrapolation.CLAMP,
83
- ),
84
- },
85
- ],
86
- width: interpolate(
87
- sv.value,
88
- [0, 100],
89
- [
90
- screenWidth - SCREEN_PADDING * 2,
91
- screenWidth - leftPosition - 12 - headerRightWidth,
92
- ],
93
- Extrapolation.CLAMP,
94
- ),
95
- }));
74
+ const height = animated.current.interpolate({
75
+ inputRange: [0, 100],
76
+ outputRange: [heightHeader + 52, heightHeader],
77
+ extrapolate: 'clamp',
78
+ });
96
79
 
97
- const searchBackgroundStyle = useAnimatedStyle(() => {
98
- const t = Math.min(Math.max(sv.value / 100, 0), 1);
99
- return { backgroundColor: t === 0
100
- ? theme.colors.background.surface
101
- : theme.colors.background.default };
80
+ const translateX = animated.current.interpolate({
81
+ inputRange: [0, 100],
82
+ outputRange: [SCREEN_PADDING, leftPosition],
83
+ extrapolate: 'clamp',
102
84
  });
103
85
 
104
- const extendedHeightStyle = useAnimatedStyle(() => ({
105
- height: interpolate(
106
- sv.value,
107
- [0, 100],
108
- [heightHeader + 52, heightHeader],
109
- Extrapolation.CLAMP,
110
- ),
111
- }));
86
+ const backgroundColor = animated.current.interpolate({
87
+ inputRange: [0, 100],
88
+ outputRange: [
89
+ theme.colors.background.surface,
90
+ theme.colors.background.default,
91
+ ],
92
+ extrapolate: 'clamp',
93
+ });
94
+
95
+ if (inputSearchProps && Platform.OS === 'android') {
96
+ useShadowHeader = false;
97
+ }
112
98
 
113
99
  if (inputSearchProps) {
114
100
  return (
115
101
  <View style={[{ zIndex: 0 }, showBaseLineDebug && styles.debugBaseLine]}>
116
- <Animated.View style={heightStyle} />
102
+ <Animated.View style={{ height: height }} />
117
103
  <BackgroundImageView
118
104
  useShadowHeader={useShadowHeader}
119
105
  heightHeader={heightHeader}
120
- animatedValue={sv}
106
+ opacityBackground={opacityBackground}
121
107
  headerBackground={headerBackground}
122
108
  />
123
109
  <Animated.View
124
110
  style={[
125
111
  styles.headerBox,
126
- headerType === 'extended'
127
- ? heightStyle
128
- : { height: heightHeader },
112
+ { height: headerType === 'extended' ? height : heightHeader },
129
113
  ]}
130
114
  >
131
115
  {!!gradientColor && (
132
- <Animated.View
133
- style={[styles.extendedHeader, gradientOpacityStyle]}
116
+ <LinearGradientAnimated
117
+ colors={[gradientColor, gradientColor + '00']}
118
+ style={[styles.extendedHeader, { opacity: opacityGradient }]}
134
119
  >
135
- <LinearGradient
136
- colors={[gradientColor, gradientColor + '00']}
137
- style={StyleSheet.absoluteFill}
138
- >
139
- {!!theme.assets?.headerBackground && (
140
- <Image
141
- style={styles.headerBackground}
142
- source={{ uri: theme.assets?.headerBackground }}
143
- loading={false}
144
- />
145
- )}
146
- </LinearGradient>
147
- </Animated.View>
120
+ {!!theme.assets?.headerBackground && (
121
+ <Image
122
+ style={styles.headerBackground}
123
+ source={{ uri: theme.assets?.headerBackground }}
124
+ loading={false}
125
+ />
126
+ )}
127
+ </LinearGradientAnimated>
148
128
  )}
149
129
  </Animated.View>
150
130
  <Animated.View
151
- style={[
152
- {
153
- justifyContent: 'flex-end',
154
- position: 'absolute',
155
- zIndex: 2,
156
- },
157
- heightStyle,
158
- ]}
131
+ style={{
132
+ justifyContent: 'flex-end',
133
+ height,
134
+ position: 'absolute',
135
+ zIndex: 2,
136
+ }}
159
137
  >
160
138
  <Animated.View
161
- style={[{ marginVertical: Spacing.S }, searchTranslateStyle]}
139
+ style={{
140
+ transform: [{ translateX }],
141
+ marginVertical: Spacing.S,
142
+ width: animated.current.interpolate({
143
+ inputRange: [0, 100],
144
+ outputRange: [
145
+ screenWidth - SCREEN_PADDING * 2,
146
+ screenWidth - leftPosition - 12 - headerRightWidth,
147
+ ],
148
+ extrapolate: 'clamp',
149
+ }),
150
+ }}
162
151
  >
163
- <Animated.View
164
- style={[
165
- { borderRadius: Radius.XL },
166
- searchBackgroundStyle,
167
- ]}
168
- >
152
+ <Animated.View style={{ backgroundColor, borderRadius: Radius.XL }}>
169
153
  <InputSearch
170
154
  {...inputSearchProps}
171
155
  ref={inputSearchRef}
@@ -185,26 +169,22 @@ const HeaderExtendHeader: React.FC<{
185
169
  <BackgroundImageView
186
170
  useShadowHeader={useShadowHeader}
187
171
  heightHeader={heightHeader}
188
- animatedValue={sv}
172
+ opacityBackground={opacityBackground}
189
173
  headerBackground={headerBackground}
190
174
  />
191
175
  {!!gradientColor && (
192
- <Animated.View
193
- style={[styles.extendedHeader, gradientOpacityStyle, extendedHeightStyle]}
176
+ <LinearGradientAnimated
177
+ colors={[gradientColor, gradientColor + '00']}
178
+ style={[styles.extendedHeader, { opacity: opacityGradient }]}
194
179
  >
195
- <LinearGradient
196
- colors={[gradientColor, gradientColor + '00']}
197
- style={StyleSheet.absoluteFill}
198
- >
199
- {!!headerBackground && (
200
- <Image
201
- style={styles.headerBackground}
202
- source={{ uri: headerBackground }}
203
- loading={false}
204
- />
205
- )}
206
- </LinearGradient>
207
- </Animated.View>
180
+ {!!headerBackground && (
181
+ <Image
182
+ style={styles.headerBackground}
183
+ source={{ uri: headerBackground }}
184
+ loading={false}
185
+ />
186
+ )}
187
+ </LinearGradientAnimated>
208
188
  )}
209
189
  <View style={{ height: heightHeader }} />
210
190
  </View>
@@ -1,16 +1,11 @@
1
1
  import React, { useContext } from 'react';
2
2
  import {
3
+ Animated,
3
4
  Dimensions,
4
5
  StyleSheet,
5
6
  TouchableOpacity,
6
7
  View,
7
8
  } from 'react-native';
8
- import Animated, {
9
- Extrapolation,
10
- interpolate,
11
- useAnimatedStyle,
12
- type SharedValue,
13
- } from 'react-native-reanimated';
14
9
  import { ApplicationContext, MiniAppContext } from '../../Context';
15
10
  import { exportFontFamily, Text, useScaleSize } from '../../Text';
16
11
  import { Colors, Radius, Spacing, Styles } from '../../Consts';
@@ -23,45 +18,21 @@ import { Image } from '../../Image';
23
18
  import { Icon } from '../../Icon';
24
19
  import { Skeleton } from '../../Skeleton';
25
20
 
26
- type HeaderTitleInterpolate = {
27
- inputRange: number[];
28
- outputRange: number[];
29
- };
30
-
31
- type HeaderTitleExtraProps = {
32
- animatedValue?: SharedValue<number>;
33
- interpolate?: HeaderTitleInterpolate;
34
- tintColor?: string;
35
- children?: React.ReactNode;
36
- };
37
-
38
21
  /**
39
22
  * default header title used for nav
40
23
  */
41
- const HeaderTitle: React.FC<HeaderTitleExtraProps & { [key: string]: any }> = props => {
24
+ const HeaderTitle: React.FC<any> = props => {
42
25
  const context = useContext<any>(MiniAppContext);
43
26
 
44
27
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
45
28
 
46
- const interpolateConfig = props.interpolate ?? {
47
- inputRange: [0, 200],
48
- outputRange: [0, 1],
49
- };
50
- const animatedValue = props.animatedValue;
51
-
52
- const animatedStyle = useAnimatedStyle(() => {
53
- if (!animatedValue) {
54
- return { opacity: 1 };
55
- }
56
- return {
57
- opacity: interpolate(
58
- animatedValue.value,
59
- interpolateConfig.inputRange,
60
- interpolateConfig.outputRange,
61
- Extrapolation.CLAMP,
62
- ),
63
- };
64
- });
29
+ const opacity = props.animatedValue?.interpolate(
30
+ props.interpolate ?? {
31
+ inputRange: [0, 200],
32
+ outputRange: [0, 1],
33
+ extrapolate: 'clamp',
34
+ },
35
+ );
65
36
 
66
37
  return (
67
38
  <View
@@ -86,9 +57,9 @@ const HeaderTitle: React.FC<HeaderTitleExtraProps & { [key: string]: any }> = pr
86
57
  },
87
58
  {
88
59
  fontFamily: exportFontFamily('bold', 'action_xs_bold'),
60
+ opacity,
89
61
  color: props.tintColor,
90
62
  },
91
- animatedStyle,
92
63
  ]}
93
64
  numberOfLines={1}
94
65
  />
@@ -1,16 +1,13 @@
1
1
  import { Colors, Radius, Spacing, Styles } from '../../Consts';
2
2
  import { InputRef, InputSearch } from '../../Input';
3
3
  import {
4
+ Animated,
4
5
  Dimensions,
5
6
  StyleSheet,
6
7
  TouchableOpacity,
7
8
  View,
8
9
  } from 'react-native';
9
- import Animated, {
10
- useAnimatedStyle,
11
- useSharedValue,
12
- } from 'react-native-reanimated';
13
- import React, { useContext } from 'react';
10
+ import React, { useContext, useEffect, useRef } from 'react';
14
11
  import { SearchHeaderProps } from '../types';
15
12
  import { ApplicationContext, MiniAppContext } from '../../Context';
16
13
  import { Text } from '../../Text';
@@ -31,18 +28,28 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
31
28
  const BACK_WIDTH = 28;
32
29
  const { width: screenWidth } = Dimensions.get('window');
33
30
 
34
- const fallback = useSharedValue(0);
35
- const sv = animatedValue ?? fallback;
31
+ const animated = useRef(new Animated.Value(0));
36
32
  const leftPosition = props?.leftPosition ?? BACK_WIDTH + 20;
37
33
  const headerRightWidth = props?.headerRightWidth ?? 73;
38
34
 
39
- const backgroundStyle = useAnimatedStyle(() => {
40
- const t = Math.min(Math.max(sv.value / 100, 0), 1);
41
- return {
42
- backgroundColor: t === 0
43
- ? theme.colors.background.surface
44
- : theme.colors.background.default,
35
+ useEffect(() => {
36
+ const listener = animatedValue?.addListener(({ value }) => {
37
+ animated.current.setValue(value);
38
+ });
39
+ return () => {
40
+ if (listener) {
41
+ animatedValue?.removeListener(listener);
42
+ }
45
43
  };
44
+ }, [animatedValue]);
45
+
46
+ const backgroundColor = animated.current?.interpolate({
47
+ inputRange: [0, 100],
48
+ outputRange: [
49
+ theme.colors.background.surface,
50
+ theme.colors.background.default,
51
+ ],
52
+ extrapolate: 'clamp',
46
53
  });
47
54
 
48
55
  const goBack = () => {
@@ -84,9 +91,7 @@ const SearchHeader = React.forwardRef<InputRef, SearchHeaderProps>(
84
91
  },
85
92
  ]}
86
93
  >
87
- <Animated.View
88
- style={[{ borderRadius: Radius.XL }, backgroundStyle]}
89
- >
94
+ <Animated.View style={{ backgroundColor, borderRadius: Radius.XL }}>
90
95
  <InputSearch
91
96
  ref={ref}
92
97
  {...props}
@@ -2,11 +2,11 @@ import { EventArg } from '@react-navigation/core';
2
2
  import { StackNavigationOptions } from '@react-navigation/stack';
3
3
  import React, { ReactNode } from 'react';
4
4
  import {
5
+ Animated,
5
6
  TouchableOpacityProps,
6
7
  ViewProps,
7
8
  ViewStyle,
8
9
  } from 'react-native';
9
- import type { SharedValue } from 'react-native-reanimated';
10
10
  import { PopupNotifyProps } from '../Popup/types';
11
11
  import { InputRef, InputSearchProps } from '../Input';
12
12
  import Navigation from './Navigation';
@@ -258,7 +258,7 @@ export interface HeaderBackProps extends NavigationButtonProps {
258
258
  }
259
259
 
260
260
  export type HeaderBackgroundProps = {
261
- animatedValue?: SharedValue<number>;
261
+ animatedValue?: Animated.Value;
262
262
  useGradient?: boolean;
263
263
  useShadowHeader?: boolean;
264
264
  backgroundColor?: string;
@@ -298,7 +298,7 @@ export type TitleJourneyProps = {
298
298
  };
299
299
 
300
300
  export interface HeaderAnimatedProps extends ViewProps {
301
- animatedValue: SharedValue<number>;
301
+ animatedValue: Animated.Value;
302
302
  image: string;
303
303
  useScale?: boolean;
304
304
  }
@@ -342,7 +342,7 @@ export type AnimatedHeader = {
342
342
 
343
343
  export interface SearchHeaderProps extends InputSearchProps {
344
344
  ref?: React.RefObject<InputRef>;
345
- animatedValue?: SharedValue<number>;
345
+ animatedValue?: Animated.Value;
346
346
  headerRightWidth?: 0 | 74 | 110 | number;
347
347
  leftPosition?: 12 | 48 | number;
348
348
  renderButtons?: () => ReactNode;
@@ -5,8 +5,7 @@ import {
5
5
  } from '@react-navigation/stack';
6
6
  import type { HeaderTitleProps, NavigationOptions } from './types';
7
7
  import { Colors, Spacing } from '../Consts';
8
- import { AppState, Platform } from 'react-native';
9
- import type { SharedValue } from 'react-native-reanimated';
8
+ import { Animated, AppState, Platform } from 'react-native';
10
9
  import {
11
10
  MiniAppContext,
12
11
  ScreenContext,
@@ -61,7 +60,7 @@ const getModalOptions = (): StackNavigationOptions => {
61
60
  */
62
61
  const getOptions = (
63
62
  params: NavigationOptions,
64
- animatedValue?: SharedValue<number>,
63
+ animatedValue?: Animated.Value,
65
64
  ) => {
66
65
  let options: StackNavigationOptions = {};
67
66
 
@@ -132,7 +131,7 @@ const getOptions = (
132
131
 
133
132
  const exportHeaderTitle = (
134
133
  params: NavigationOptions,
135
- animatedValue?: SharedValue<number>,
134
+ animatedValue?: Animated.Value,
136
135
  ): StackNavigationOptions => {
137
136
  if (typeof params.headerTitle === 'object') {
138
137
  return {
@@ -1,75 +1,93 @@
1
- import React, { useEffect } from 'react';
2
- import { View } from 'react-native';
3
- import Animated, {
4
- cancelAnimation,
5
- useAnimatedStyle,
6
- useSharedValue,
7
- withRepeat,
8
- withSequence,
9
- withSpring,
10
- withTiming,
11
- } from 'react-native-reanimated';
1
+ import React, { useEffect, useRef } from 'react';
2
+ import { Animated, View } from 'react-native';
12
3
  import { BadgeDotProps } from './types';
13
4
  import styles from './styles';
14
5
 
15
6
  const DURATION = 500;
16
7
 
17
8
  const BadgeDotAnimation = ({ size, style }: BadgeDotProps) => {
18
- const scaleAnim = useSharedValue(1);
19
- const waveScaleAnim = useSharedValue(1);
20
- const waveOpacityAnim = useSharedValue(0);
9
+ // Refs for animated values
10
+ const scaleAnim = useRef(new Animated.Value(1)).current;
11
+ const waveScaleAnim = useRef(new Animated.Value(1)).current;
12
+ const waveOpacityAnim = useRef(new Animated.Value(0)).current;
21
13
 
22
14
  const dotStyle =
23
15
  size === 'small' ? styles.dotAnimationSmall : styles.dotAnimation;
24
16
  const waveStyle = size === 'small' ? styles.waveSmall : styles.wave;
25
17
 
26
18
  useEffect(() => {
27
- const springCfg = { damping: 5, stiffness: 30, mass: 1 };
28
-
29
- scaleAnim.value = withRepeat(
30
- withSequence(
31
- withSpring(1, springCfg),
32
- withSpring(1.1, springCfg),
33
- ),
34
- -1,
35
- false,
36
- );
37
- waveScaleAnim.value = withRepeat(
38
- withSequence(
39
- withTiming(2.5, { duration: DURATION * 3 }),
40
- withTiming(1, { duration: 0 }),
41
- ),
42
- -1,
43
- false,
44
- );
45
- waveOpacityAnim.value = withRepeat(
46
- withSequence(
47
- withTiming(0.3, { duration: DURATION * 2 }),
48
- withTiming(0, { duration: DURATION }),
49
- ),
50
- -1,
51
- false,
19
+ // Infinite loop animation for the scale and wave effect
20
+ const animation = Animated.loop(
21
+ Animated.parallel([
22
+ // Dot pulse animation
23
+ Animated.sequence([
24
+ Animated.spring(scaleAnim, {
25
+ toValue: 1, // Scale up slightly
26
+ friction: 5, // Controls the "bounciness" of the spring
27
+ tension: 30, // Controls the "stiffness" of the spring
28
+ useNativeDriver: true,
29
+ }),
30
+ Animated.spring(scaleAnim, {
31
+ toValue: 1.1,
32
+ friction: 5,
33
+ tension: 30,
34
+ useNativeDriver: true,
35
+ }),
36
+ ]), // Wave animation
37
+ Animated.sequence([
38
+ Animated.timing(waveScaleAnim, {
39
+ toValue: 2.5,
40
+ duration: DURATION * 3,
41
+ useNativeDriver: true,
42
+ }),
43
+ Animated.timing(waveScaleAnim, {
44
+ toValue: 1, // Reset wave size
45
+ duration: 0,
46
+ useNativeDriver: true,
47
+ }),
48
+ ]), // Wave opacity animation
49
+ Animated.sequence([
50
+ Animated.timing(waveOpacityAnim, {
51
+ toValue: 0.3, // Wave becomes visible
52
+ duration: DURATION * 2,
53
+ useNativeDriver: true,
54
+ }),
55
+ Animated.timing(waveOpacityAnim, {
56
+ toValue: 0, // Wave fades out
57
+ duration: DURATION,
58
+ useNativeDriver: true,
59
+ }),
60
+ ]),
61
+ ]),
52
62
  );
63
+ animation.start();
64
+
53
65
  return () => {
54
- cancelAnimation(scaleAnim);
55
- cancelAnimation(waveScaleAnim);
56
- cancelAnimation(waveOpacityAnim);
66
+ animation.stop();
57
67
  };
58
68
  }, [scaleAnim, waveOpacityAnim, waveScaleAnim]);
59
69
 
60
- const waveAnimatedStyle = useAnimatedStyle(() => ({
61
- transform: [{ scale: waveScaleAnim.value }],
62
- opacity: waveOpacityAnim.value,
63
- }));
64
-
65
- const dotAnimatedStyle = useAnimatedStyle(() => ({
66
- transform: [{ scale: scaleAnim.value }],
67
- }));
68
-
69
70
  return (
70
71
  <View style={[styles.dotAnimationContainer, style]}>
71
- <Animated.View style={[waveStyle, waveAnimatedStyle]} />
72
- <Animated.View style={[dotStyle, dotAnimatedStyle]} />
72
+ {/* Wave Animation */}
73
+ <Animated.View
74
+ style={[
75
+ waveStyle,
76
+ {
77
+ transform: [{ scale: waveScaleAnim }],
78
+ opacity: waveOpacityAnim,
79
+ },
80
+ ]}
81
+ />
82
+ {/* Dot Animation */}
83
+ <Animated.View
84
+ style={[
85
+ dotStyle,
86
+ {
87
+ transform: [{ scale: scaleAnim }],
88
+ },
89
+ ]}
90
+ />
73
91
  </View>
74
92
  );
75
93
  };
package/Button/index.tsx CHANGED
@@ -1,5 +1,6 @@
1
1
  import React, { FC, useContext, useRef } from 'react';
2
2
  import {
3
+ Animated,
3
4
  StyleSheet,
4
5
  TouchableOpacity,
5
6
  TouchableOpacityProps,
@@ -28,6 +29,8 @@ import Reanimated, {
28
29
  withTiming,
29
30
  } from 'react-native-reanimated';
30
31
 
32
+ const AnimationLinear = Animated.createAnimatedComponent(LinearGradient);
33
+
31
34
  export interface ButtonProps extends TouchableOpacityProps {
32
35
  /**
33
36
  * Defines the visual style of the button.
@@ -356,7 +359,7 @@ const Button: FC<ButtonProps> = ({
356
359
  {renderTitle()}
357
360
  {renderIcon('right')}
358
361
  {gradientPros && (
359
- <LinearGradient {...gradientPros} style={styles.gradientView} />
362
+ <AnimationLinear {...gradientPros} style={styles.gradientView} />
360
363
  )}
361
364
  {gradientPros && <View style={styles.strokeView} />}
362
365
  </Reanimated.View>