import React from 'react' import {Animated, StyleProp, View, ViewStyle} from 'react-native' import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' type CreateAnimFn = (interp: Animated.Value) => Animated.CompositeAnimation type FinishCb = () => void interface TriggeredAnimation { start: CreateAnimFn style: ( interp: Animated.Value, ) => Animated.WithAnimatedValue> } export interface TriggerableAnimatedRef { trigger: (anim: TriggeredAnimation, onFinish?: FinishCb) => void } type TriggerableAnimatedProps = React.PropsWithChildren<{}> type PropsInner = TriggerableAnimatedProps & { anim: TriggeredAnimation onFinish: () => void } export const TriggerableAnimated = React.forwardRef< TriggerableAnimatedRef, TriggerableAnimatedProps >(function TriggerableAnimatedImpl({children, ...props}, ref) { const [anim, setAnim] = React.useState( undefined, ) const [finishCb, setFinishCb] = React.useState( undefined, ) React.useImperativeHandle(ref, () => ({ trigger(v: TriggeredAnimation, cb?: FinishCb) { setFinishCb(() => cb) // note- wrap in function due to react behaviors around setstate setAnim(v) }, })) const onFinish = () => { finishCb?.() setAnim(undefined) setFinishCb(undefined) } return ( {anim ? ( {children} ) : ( children )} ) }) function AnimatingView({ anim, onFinish, children, }: React.PropsWithChildren) { const interp = useAnimatedValue(0) React.useEffect(() => { anim?.start(interp).start(() => { onFinish() }) }) const animStyle = anim?.style(interp) return {children} }