Skip to content

Commit 4d7b23d

Browse files
authored
fix(AnimatedText): improve animation handling & fix Android font weights (#1590)
1 parent 78651bb commit 4d7b23d

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

components/animated-text-carousel.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { AnimatedCenter } from "@/design-system/Center";
22
import { AnimatableText } from "@/design-system/Text/AnimatedText";
33
import { ITextProps } from "@/design-system/Text/Text.props";
4-
import { debugBorder } from "@/utils/debug-style";
54
import React, { memo, useEffect, useRef } from "react";
65
import {
76
cancelAnimation,

design-system/Text/AnimatedText.tsx

+41-13
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
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";
38
import AnimateableText from "react-native-animateable-text";
49
import Animated, {
510
AnimatedProps,
611
SharedValue,
712
useAnimatedProps,
13+
useAnimatedStyle,
814
} from "react-native-reanimated";
915
import { Text } from "./Text";
1016
import { ITextProps } from "./Text.props";
@@ -16,30 +22,52 @@ export type IAnimatedTextProps = AnimatedProps<ITextProps>;
1622
export const AnimatedText = Animated.createAnimatedComponent(Text);
1723

1824
// 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"> & {
2230
text: SharedValue<string>;
31+
// Required to specify text styling - will be merged with theme's default text color
32+
style: StyleProp<TextStyle>;
2333
};
2434

2535
export function AnimatableText({ style, text, ...rest }: IAnimatableTextProps) {
2636
const { theme } = useAppTheme();
2737

28-
const animatedProps = useAnimatedProps(() => {
29-
return {
30-
text: text.value,
38+
const animatedStyle = useAnimatedStyle(() => {
39+
const baseStyle: TextStyle = {
40+
color: theme.colors.text.primary,
3141
};
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;
3261
});
3362

63+
const animatedProps = useAnimatedProps(() => ({
64+
text: text.value,
65+
}));
66+
3467
return (
3568
<AnimateableText
3669
animatedProps={animatedProps}
37-
style={[
38-
{
39-
color: theme.colors.text.primary,
40-
},
41-
style,
42-
]}
70+
style={animatedStyle}
4371
{...rest}
4472
/>
4573
);

0 commit comments

Comments
 (0)