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

PropTypeDefaultDescription
intensity'subtle' | 'standard' | 'expressive'"standard"Scales the press delta. subtle=0.5×, standard=1×, expressive=1.25×.
enableHapticsbooleantrueWhen false, resolveHaptic() returns null for all intents.
pressScalenumber0.96Default target scale on press (before intensity scaling).
pressOpacitynumber0.88Default target opacity on press (before intensity scaling).
defaultSpringstring"snappy"Which spring preset motion hooks use when no spring is explicitly passed.
reduceMotionbooleanundefinedOverride 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>
  );
}