Motion.Text
Animatable Text. animate / initial / exit / gesture are typed against TextStyle.
import { Motion } from '@rootnative/inertia'
export function Heading({ visible }: { visible: boolean }) {
return (
<Motion.Text
initial={{ opacity: 0, translateY: 8 }}
animate={{ opacity: visible ? 1 : 0, translateY: visible ? 0 : 8 }}
transition={{ type: 'spring' }}
style={headingStyles.title}
>
Hello
</Motion.Text>
)
}
Tree-shaken import
import { MotionText } from '@rootnative/inertia/text'
Animatable keys
opacity, translateX, translateY, scale, scaleX, scaleY, rotate, rotateX, rotateY, width, height, borderRadius, color, backgroundColor, plus the layout numerics listed in Animatable properties.
Text metrics — fontSize, letterSpacing, and lineHeight animate as of 0.0.5 (before that they typechecked but were silently dropped, and the docs recommended a hand-rolled useAnimatedStyle; that workaround is no longer needed). They're TextStyle-only, so they're rejected at compile time on Motion.View and Motion.Image.
<Motion.Text
initial={{ fontSize: 14, letterSpacing: 0 }}
animate={{ fontSize: 20, letterSpacing: 1.5 }}
transition={{ type: 'spring', tension: 200, friction: 18 }}
>
Scaling headline
</Motion.Text>
Each of these re-measures the text every frame, which is heavier than the transform path. When you only need the text to look bigger and reflow isn't wanted, animate scale instead — it composites without re-measuring. Use fontSize when surrounding content genuinely must reflow around the new size.
<Motion.Text
initial={{ color: '#6b7280' }}
animate={{ color: pressed ? '#4f46e5' : '#6b7280' }}
transition={{ type: 'timing', duration: 150 }}
>
Tap me
</Motion.Text>