react-native-micro-interactions
Version:
Effortlessly enhance your React Native components with subtle micro-interactions and animations.
89 lines (86 loc) • 3.05 kB
JavaScript
;
import Animated from "react-native-reanimated";
import { useAnimation } from "../hooks/useAnimation.js";
import { Text, TouchableOpacity } from "react-native";
import React, { forwardRef, useEffect, useImperativeHandle, useMemo } from "react";
import AnimatedChild from "./AnimatedChild.js";
import { useRunAnimation } from "../hooks/useRunAnimation.js";
import { isComponentTouchable } from "../utils/utilityFunctions.js";
import { jsx as _jsx } from "react/jsx-runtime";
const AnimatedWrapper = /*#__PURE__*/forwardRef(({
children,
animationTrigger,
animationType,
animationOptions,
isGroup = false
}, ref) => {
if (animationType === "text_slide_vertical" || animationType === "text_slide_horizontal" && children.type !== Text) {
return children;
}
const {
animatedStyle,
runIndividualAnimation
} = useAnimation(animationType, animationOptions);
const {
addAnimation,
runAnimation,
runCurrentAnimation
} = useRunAnimation(runIndividualAnimation, isGroup);
const AnimatedComponent = useMemo(() => {
return Animated.createAnimatedComponent(children.type);
}, [children.type]);
const childElements = React.Children.toArray(children.props.children);
const {
style,
onPress,
onLongPress,
...restProps
} = children.props;
const combinedStyle = [animatedStyle, style];
useImperativeHandle(ref, () => ({
runAnimation // Expose runAnimation to the parent component
}));
useEffect(() => {
if (animationTrigger === "init") {
runCurrentAnimation();
}
}, [children.props.children]);
// render animated grandchildren in case of group animations
const mapGrandChildren = () => childElements.map((child, index) => {
if (/*#__PURE__*/React.isValidElement(child)) {
return /*#__PURE__*/_jsx(AnimatedChild, {
animationOptions: animationOptions,
animationType: animationType,
addAnimation: addAnimation,
children: child
}, child.key || index);
}
return child;
});
// If the child provided is already a touchable kind, we dont need to wrap with additional touchable opacity
if (isComponentTouchable(children)) {
return /*#__PURE__*/_jsx(AnimatedComponent, {
...restProps,
style: isGroup ? style : combinedStyle,
onPress: (...args) => {
if (animationTrigger === "press") {
runCurrentAnimation();
}
onPress?.(...args);
},
children: isGroup ? mapGrandChildren() : children.props.children
});
}
return /*#__PURE__*/_jsx(TouchableOpacity, {
activeOpacity: 1,
onPressIn: animationTrigger === "press" ? runCurrentAnimation : undefined,
onLongPress: animationTrigger === "long_press" ? runCurrentAnimation : undefined,
children: /*#__PURE__*/_jsx(AnimatedComponent, {
...restProps,
style: isGroup ? style : combinedStyle,
children: isGroup ? mapGrandChildren() : children.props.children
})
});
});
export default AnimatedWrapper;
//# sourceMappingURL=AnimatedWrapper.js.map