Motion
InteractionProvider
The global interaction policy controller. It governs how pronounced press animations feel, which spring preset runs by default, and whether haptics are enabled. All motion hooks read from this context — one config controls your entire app's feel.
Import
typescript
import { InteractionProvider, useInteraction } from 'reactnatively';
// or
import { InteractionProvider, useInteraction } from 'reactnatively/animations';Setup
ReactnativelyProvider already wraps your app in InteractionProvider. Pass the interaction prop to configure it:
app/_layout.tsx
import { ReactnativelyProvider } from 'reactnatively';
export default function RootLayout() {
return (
<ReactnativelyProvider
interaction={{
intensity: 'standard', // 'subtle' | 'standard' | 'expressive'
enableHaptics: true,
defaultSpring: 'snappy', // 'snappy' | 'liquid' | 'reveal' | 'bounce' | 'precise'
}}
>
<App />
</ReactnativelyProvider>
);
}Policy props
| Prop | Type | Default | Description |
|---|---|---|---|
| intensity | 'subtle' | 'standard' | 'expressive' | "standard" | Scales the press delta. subtle=0.5×, standard=1×, expressive=1.25×. |
| enableHaptics | boolean | true | When false, resolveHaptic() returns null for all intents. |
| pressScale | number | 0.96 | Default target scale on press (before intensity scaling). |
| pressOpacity | number | 0.88 | Default target opacity on press (before intensity scaling). |
| defaultSpring | string | "snappy" | Which spring preset motion hooks use when no spring is explicitly passed. |
| reduceMotion | boolean | undefined | Override to force reduced motion regardless of OS setting. |
useInteraction
Read and use the interaction policy in your own components:
CustomPressable.tsx
1import { useInteraction } from 'reactnatively';2import { withSpring, useSharedValue, useAnimatedStyle } from 'react-native-reanimated';34export function CustomPressable() {5 const interaction = useInteraction();6 const pressed = useSharedValue(0);78 const spring = interaction.resolveSpring('snappy');9 const { scale, opacity } = interaction.resolvePress(0.95, 0.85);1011 const style = useAnimatedStyle(() => ({12 transform: [{ scale: pressed.value === 1 ? scale : 1 }],13 opacity: pressed.value === 1 ? opacity : 1,14 }));1516 return (17 // ... Pressable using spring and style18 );19}Nested providers
Nest a second InteractionProvider to change intensity in a specific screen or section — for example, making a game screen more expressive without affecting the rest of the app:
tsx
import { InteractionProvider } from 'reactnatively';
export function GameScreen() {
return (
<InteractionProvider policy={{ intensity: 'expressive', defaultSpring: 'bounce' }}>
<GameUI />
</InteractionProvider>
);
}