react-native-irano
Version:
A customizable cross-platform toast notification library for React Native.
159 lines (158 loc) • 4.51 kB
JavaScript
"use strict";
import { View, StyleSheet, Text } from 'react-native';
import { useEffect, memo } from 'react';
import Animated, { Easing, FadeIn, SlideInDown, SlideInUp, SlideOutDown, SlideOutUp, useSharedValue, withTiming, useAnimatedProps, useAnimatedStyle } from 'react-native-reanimated';
import Svg, { Path } from 'react-native-svg';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
const AnimatedPath = Animated.createAnimatedComponent(Path);
const Icon = ({
preset,
animatedProps,
pathAnimatedProps
}) => /*#__PURE__*/_jsx(Svg, {
style: styles.icon,
width: "30",
height: "30",
viewBox: "0 0 24 24",
children: /*#__PURE__*/_jsx(AnimatedPath, {
d: preset === 'error' ? 'M6 18L18 6M6 6l12 12' : 'M5 12.5l5 5 10-10',
stroke: "gray",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
strokeDasharray: "22",
fill: "none",
...pathAnimatedProps,
animatedProps: animatedProps
})
});
const Toast = /*#__PURE__*/memo(({
title,
subtitle,
preset = 'success',
pathProps,
textContainerProps,
textContainerStyle,
toastContainerProps,
toastContainerStyle,
titleProps,
titleStyle,
subtitleProps,
subtitleStyle,
iconContainerStyle,
toastMainContainerStyle,
MAX_WIDTH = 340,
autoHideDuration = 5000,
position = 'top',
onHide
}) => {
const strokeDashoffset = useSharedValue(22);
const widthValue = useSharedValue(55);
useEffect(() => {
const animationTimeouts = [setTimeout(() => {
strokeDashoffset.value = withTiming(0, {
duration: 300,
easing: Easing.out(Easing.ease)
});
}, 400), setTimeout(() => {
widthValue.value = withTiming(MAX_WIDTH, {
duration: 300,
easing: Easing.out(Easing.elastic(0.7))
});
}, 600), setTimeout(() => {
onHide();
}, autoHideDuration)];
return () => animationTimeouts.forEach(clearTimeout);
}, [MAX_WIDTH, strokeDashoffset, widthValue, onHide, autoHideDuration]);
const animatedProps = useAnimatedProps(() => ({
strokeDashoffset: strokeDashoffset.value
}));
const animatedStyle = useAnimatedStyle(() => ({
width: widthValue.value
}));
return /*#__PURE__*/_jsx(Animated.View, {
style: [styles.toastContainer, position === 'bottom' ? styles.toastContainerBottom : styles.toastContainerTop, toastContainerStyle],
entering: (position === 'top' ? SlideInUp : SlideInDown).springify().damping(10).mass(0.5),
exiting: position === 'top' ? SlideOutUp : SlideOutDown,
...toastContainerProps,
children: /*#__PURE__*/_jsxs(Animated.View, {
style: [animatedStyle, styles.toastContent, toastMainContainerStyle],
children: [/*#__PURE__*/_jsx(View, {
onTouchEnd: onHide,
style: [styles.iconContainer, iconContainerStyle],
children: /*#__PURE__*/_jsx(Icon, {
preset: preset,
animatedProps: animatedProps,
pathAnimatedProps: pathProps
})
}), /*#__PURE__*/_jsxs(Animated.View, {
style: [styles.textContainer, {
width: MAX_WIDTH * 0.75
}, textContainerStyle],
entering: FadeIn.delay(900),
...textContainerProps,
children: [/*#__PURE__*/_jsx(Text, {
allowFontScaling: true,
numberOfLines: 1,
ellipsizeMode: "tail",
style: [styles.text, titleStyle],
...titleProps,
children: title
}), /*#__PURE__*/_jsx(Text, {
allowFontScaling: true,
numberOfLines: 1,
ellipsizeMode: "tail",
style: [styles.subtitleStyle, subtitleStyle],
...subtitleProps,
children: subtitle
})]
})]
})
});
});
const styles = StyleSheet.create({
toastContainer: {
position: 'absolute',
width: '100%',
alignItems: 'center'
},
toastContainerBottom: {
bottom: '10%'
},
toastContainerTop: {
top: '10%'
},
toastContent: {
height: 55,
backgroundColor: '#f0f0f0',
borderRadius: 25,
flexDirection: 'row',
alignItems: 'center',
paddingHorizontal: 8
},
icon: {
margin: 2
},
iconContainer: {
padding: 4,
borderRadius: 100,
backgroundColor: 'white'
},
textContainer: {
width: 230,
marginLeft: 10
},
text: {
fontSize: 16,
color: '#333',
fontWeight: 'bold'
},
subtitleStyle: {
fontSize: 14,
color: '#666',
marginTop: 2,
textAlign: 'center'
}
});
export default Toast;
//# sourceMappingURL=toast.js.map