1
1
import { useAppTheme } from "@/theme/useAppTheme" ;
2
- import { TextProps as RNTextProps } from "react-native" ;
2
+ import {
3
+ TextProps as RNTextProps ,
4
+ TextStyle ,
5
+ Platform ,
6
+ StyleProp ,
7
+ } from "react-native" ;
3
8
import AnimateableText from "react-native-animateable-text" ;
4
9
import Animated , {
5
10
AnimatedProps ,
6
11
SharedValue ,
7
12
useAnimatedProps ,
13
+ useAnimatedStyle ,
8
14
} from "react-native-reanimated" ;
9
15
import { Text } from "./Text" ;
10
16
import { ITextProps } from "./Text.props" ;
@@ -16,30 +22,52 @@ export type IAnimatedTextProps = AnimatedProps<ITextProps>;
16
22
export const AnimatedText = Animated . createAnimatedComponent ( Text ) ;
17
23
18
24
// A specialized text component that efficiently updates text content using SharedValue
19
- // Optimized for frequent text changes without causing re-renders
20
- // Uses react-native-animateable-text under the hood for better performance
21
- export type IAnimatableTextProps = RNTextProps & {
25
+
26
+ // We omit 'style' from RNTextProps and explicitly redefine it to ensure proper type checking
27
+ // with Reanimated's StyleProp<TextStyle>. This prevents type conflicts between React Native's
28
+ // default style types and Reanimated's animated style types.
29
+ export type IAnimatableTextProps = Omit < RNTextProps , "style" > & {
22
30
text : SharedValue < string > ;
31
+ // Required to specify text styling - will be merged with theme's default text color
32
+ style : StyleProp < TextStyle > ;
23
33
} ;
24
34
25
35
export function AnimatableText ( { style, text, ...rest } : IAnimatableTextProps ) {
26
36
const { theme } = useAppTheme ( ) ;
27
37
28
- const animatedProps = useAnimatedProps ( ( ) => {
29
- return {
30
- text : text . value ,
38
+ const animatedStyle = useAnimatedStyle ( ( ) => {
39
+ const baseStyle : TextStyle = {
40
+ color : theme . colors . text . primary ,
31
41
} ;
42
+
43
+ // Special handling for Android font weight due to a known issue in react-native-animateable-text
44
+ // where Android requires fontWeight to be a string, while the style type expects a number
45
+ // This workaround ensures consistent font weight behavior across platforms
46
+ if (
47
+ Platform . OS === "android" &&
48
+ style &&
49
+ typeof style === "object" &&
50
+ ! Array . isArray ( style ) &&
51
+ "fontWeight" in style
52
+ ) {
53
+ baseStyle . fontWeight = String (
54
+ style . fontWeight
55
+ ) as TextStyle [ "fontWeight" ] ;
56
+ } else if ( style && typeof style === "object" && ! Array . isArray ( style ) ) {
57
+ Object . assign ( baseStyle , style ) ;
58
+ }
59
+
60
+ return baseStyle ;
32
61
} ) ;
33
62
63
+ const animatedProps = useAnimatedProps ( ( ) => ( {
64
+ text : text . value ,
65
+ } ) ) ;
66
+
34
67
return (
35
68
< AnimateableText
36
69
animatedProps = { animatedProps }
37
- style = { [
38
- {
39
- color : theme . colors . text . primary ,
40
- } ,
41
- style ,
42
- ] }
70
+ style = { animatedStyle }
43
71
{ ...rest }
44
72
/>
45
73
) ;
0 commit comments