Skip to content
react-native-strx v1.0.0-beta.1

Interaction & layout

Layout transitions

Animate size and position changes with layout-* tokens, and control how they are inherited.

When a component's size or position changes, because content appeared, text wrapped, or a sibling was removed, a layout-* token animates it to the new layout on the UI thread.

1<Strx.View animate="layout-spring">2  <Strx.Text>Title</Strx.Text>3  {open && <Strx.Text>Expanded content</Strx.Text>}4</Strx.View>

Layout tokens

TokenBehaviorMotion
layout-linear
Timing transition.
300ms, or duration-* / provider duration
layout-spring
Spring transition.
damping 15, stiffness 120, mass 1
layout-fade
Timing transition that also fades the view in.
300ms, or duration-* / provider duration
layout-spring-stiff
Stiffer spring transition.
damping 20, stiffness 180, mass 0.9
layout-spring-bouncy
Bouncier spring transition.
damping 10, stiffness 105, mass 1

Layout tokens are passed to Reanimated's layout prop. The linear and fade transitions use duration-* from the same group, then Strx.Provider's motionPreset.duration, then 300ms. Spring transitions use their own parameters.

<Strx.View animate="layout-linear duration-180" />

A layout token combines freely with an entrance, transition or exit in the same group:

<Strx.View animate="fade-in from:translate-y-12 layout-spring exit:opacity-0" />

Inheritance

A STRX component animates its layout when:

  1. it has its own layout-* token, or
  2. it inherits one, from the nearest STRX ancestor that has a layout transition, or from the nearest Strx.LayoutGroup.

So one token on a container animates every STRX descendant inside it:

1<Strx.View animate="layout-spring">2  <Strx.View>{/* inherits layout-spring */}</Strx.View>3  <Strx.Text>{/* inherits layout-spring */}</Strx.Text>4</Strx.View>

Inheritance only flows down. A child with a layout-* token does not make its parent animate. When content appearing inside a container should also resize the container smoothly, put the token on the container, or wrap the region in a Strx.LayoutGroup:

1// the card resizes smoothly; the new text fades in2<Strx.View animate="layout-spring">3  {open && <Strx.Text animate="fade-in">Details</Strx.Text>}4</Strx.View>
Only STRX components

Inheritance passes through React context to STRX components. Plain React Native Views in between don't break the chain, but they don't animate either.

Stopping inheritance

Set layoutPropagation="none" to ignore inherited transitions for a component and its descendants. The component then only uses its own layout-* token, if any, and that is what its children inherit:

1<Strx.View animate="layout-spring">2  <Strx.View layoutPropagation="none">3    <Strx.Text>Layout changes here are not animated.</Strx.Text>4  </Strx.View>5</Strx.View>

Use it for regions that change size often (a live counter, a text input) where animation would feel laggy, or for independent widgets inside an animated container.

Clipping

While a view animates to a smaller size, its content can overflow. layoutClip adds overflow: "hidden" while a layout transition applies (own or inherited):

<Strx.View animate="layout-spring" layoutClip>
  {open && <LongContent />}
</Strx.View>

It's opt-in so text shadows and badges aren't clipped unexpectedly.

Cost

Components without a layout transition get no Reanimated layout prop at all, so adding STRX to a large tree costs nothing for layout. Once a component has had a layout transition, it keeps a no-op transition instead of removing the prop, which avoids churn in the native view tree.

Long lists

For long scrolling lists, prefer Reanimated's Animated.FlatList with itemLayoutAnimation over a layout-* token on every row. Rows can still use STRX for entrance and exit:

1import Animated, { LinearTransition } from "react-native-reanimated";23<Animated.FlatList4  data={items}5  keyExtractor={item => item.id}6  itemLayoutAnimation={LinearTransition}7  renderItem={({ item }) => (8    <Strx.View animate="fade-in exit:opacity-0">9      <Row item={item} />10    </Strx.View>11  )}12/>;

Reduce Motion

Under Reduce Motion, layout changes apply immediately. See Accessibility.

Layout transitions vs. transition-layout

layout-*transition-layout
Triggered by
Any native layout change (content, siblings, flexbox)
Changes to width/height/position in your style
Animates to
The measured layout
The value you set
Inherited
Yes, by STRX descendants
No
Esc