import React, { forwardRef, ComponentType, FunctionComponent } from 'react' import type { ImageStyle, TextStyle, ViewStyle } from 'react-native' import type { MotiProps } from './types' import { useMotify } from './use-map-animate-to-style' import Animated, { BaseAnimationBuilder, EntryExitAnimationFunction, LayoutAnimationFunction, } from 'react-native-reanimated' // copied from reanimated // if we use Animated.AnimateProps // then we get this TypeScript error: // Exported variable 'View' has or is using name 'AnimatedNode' from external module "react-native-reanimated" but cannot be named. type AnimatedProps = { animatedProps?: Partial layout?: | BaseAnimationBuilder | LayoutAnimationFunction | typeof BaseAnimationBuilder entering?: | BaseAnimationBuilder | typeof BaseAnimationBuilder | EntryExitAnimationFunction | Keyframe exiting?: | BaseAnimationBuilder | typeof BaseAnimationBuilder | EntryExitAnimationFunction | Keyframe } export default function motify< Style, Props extends { style?: Style }, Ref, ExtraProps, Animate = ViewStyle | ImageStyle | TextStyle >(ComponentWithoutAnimation: ComponentType) { const Component = Animated.createAnimatedComponent( ComponentWithoutAnimation as FunctionComponent ) const withAnimations = () => { const Motified = forwardRef< Ref, Props & AnimatedProps & MotiProps & ExtraProps & { children?: React.ReactNode } >(function Moti( { animate, style, from, transition, delay, state, stylePriority, onDidAnimate, exit, animateInitialState, exitTransition, ...props }, ref ) { const animated = useMotify({ animate, from, transition, delay, state, stylePriority, onDidAnimate, exit, exitTransition, animateInitialState, }) return ( ) }) Motified.displayName = `Moti.${ Component.displayName || Component.name || 'NoName' }` return Motified } return withAnimations }