react-native-toast-notifications
Version:
[![Version][version-badge]][package] [![MIT License][license-badge]][license]
258 lines (227 loc) • 7.21 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useRef, useEffect, useState } from "react";
import { View, StyleSheet, Animated, Text, TouchableWithoutFeedback, PanResponder, Platform } from "react-native";
import { useDimensions } from "./utils/useDimensions";
const Toast = props => {
let {
id,
onDestroy,
icon,
type = "normal",
message,
duration = 5000,
style,
textStyle,
animationDuration = 250,
animationType = "slide-in",
successIcon,
dangerIcon,
warningIcon,
successColor,
dangerColor,
warningColor,
normalColor,
placement,
swipeEnabled,
onPress
} = props;
const containerRef = useRef(null);
const [animation] = useState(new Animated.Value(0));
const panResponderRef = useRef();
const panResponderAnimRef = useRef();
const closeTimeoutRef = useRef(null);
const dims = useDimensions();
useEffect(() => {
Animated.timing(animation, {
toValue: 1,
useNativeDriver: Platform.OS !== "web",
duration: animationDuration
}).start();
if (duration !== 0 && typeof duration === "number") {
closeTimeoutRef.current = setTimeout(() => {
handleClose();
}, duration);
}
return () => {
closeTimeoutRef.current && clearTimeout(closeTimeoutRef.current);
};
}, [duration]); // Handles hide & hideAll
useEffect(() => {
if (!props.open) {
// Unregister close timeout
closeTimeoutRef.current && clearTimeout(closeTimeoutRef.current); // Close animation them remove from stack.
handleClose();
}
}, [props.open]);
const handleClose = () => {
Animated.timing(animation, {
toValue: 0,
useNativeDriver: Platform.OS !== "web",
duration: animationDuration
}).start(() => onDestroy());
};
const panReleaseToLeft = gestureState => {
Animated.timing(getPanResponderAnim(), {
toValue: {
x: -dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: Platform.OS !== "web",
duration: 250
}).start(() => onDestroy());
};
const panReleaseToRight = gestureState => {
Animated.timing(getPanResponderAnim(), {
toValue: {
x: dims.width / 10 * 9,
y: gestureState.dy
},
useNativeDriver: Platform.OS !== "web",
duration: 250
}).start(() => onDestroy());
};
const getPanResponder = () => {
if (panResponderRef.current) return panResponderRef.current;
const swipeThreshold = Platform.OS === "android" ? 10 : 0;
panResponderRef.current = PanResponder.create({
onMoveShouldSetPanResponder: (_, gestureState) => {
//return true if user is swiping, return false if it's a single click
return Math.abs(gestureState.dx) > swipeThreshold || Math.abs(gestureState.dy) > swipeThreshold;
},
onPanResponderMove: (_, gestureState) => {
var _getPanResponderAnim;
(_getPanResponderAnim = getPanResponderAnim()) === null || _getPanResponderAnim === void 0 ? void 0 : _getPanResponderAnim.setValue({
x: gestureState.dx,
y: gestureState.dy
});
},
onPanResponderRelease: (_, gestureState) => {
if (gestureState.dx > 50) {
panReleaseToRight(gestureState);
} else if (gestureState.dx < -50) {
panReleaseToLeft(gestureState);
} else {
Animated.spring(getPanResponderAnim(), {
toValue: {
x: 0,
y: 0
},
useNativeDriver: Platform.OS !== "web"
}).start();
}
}
});
return panResponderRef.current;
};
const getPanResponderAnim = () => {
if (panResponderAnimRef.current) return panResponderAnimRef.current;
panResponderAnimRef.current = new Animated.ValueXY({
x: 0,
y: 0
});
return panResponderAnimRef.current;
};
if (icon === undefined) {
switch (type) {
case "success":
{
if (successIcon) {
icon = successIcon;
}
break;
}
case "danger":
{
if (dangerIcon) {
icon = dangerIcon;
}
break;
}
case "warning":
{
if (warningIcon) {
icon = warningIcon;
}
break;
}
}
}
let backgroundColor = "";
switch (type) {
case "success":
backgroundColor = successColor || "rgb(46, 125, 50)";
break;
case "danger":
backgroundColor = dangerColor || "rgb(211, 47, 47)";
break;
case "warning":
backgroundColor = warningColor || "rgb(237, 108, 2)";
break;
default:
backgroundColor = normalColor || "#333";
}
const animationStyle = {
opacity: animation,
transform: [{
translateY: animation.interpolate({
inputRange: [0, 1],
outputRange: placement === "bottom" ? [20, 0] : [-20, 0] // 0 : 150, 0.5 : 75, 1 : 0
})
}]
};
if (swipeEnabled) {
var _animationStyle$trans;
(_animationStyle$trans = animationStyle.transform) === null || _animationStyle$trans === void 0 ? void 0 : _animationStyle$trans.push(getPanResponderAnim().getTranslateTransform()[0]);
}
if (animationType === "zoom-in") {
var _animationStyle$trans2;
(_animationStyle$trans2 = animationStyle.transform) === null || _animationStyle$trans2 === void 0 ? void 0 : _animationStyle$trans2.push({
scale: animation.interpolate({
inputRange: [0, 1],
outputRange: [0.7, 1]
})
});
}
return /*#__PURE__*/React.createElement(Animated.View, _extends({
pointerEvents: "box-none",
ref: containerRef
}, swipeEnabled ? getPanResponder().panHandlers : null, {
style: [styles.container, animationStyle]
}), props.renderType && props.renderType[type] ? props.renderType[type](props) : props.renderToast ? props.renderToast(props) : /*#__PURE__*/React.createElement(TouchableWithoutFeedback, {
disabled: !onPress,
onPress: () => onPress && onPress(id)
}, /*#__PURE__*/React.createElement(View, {
style: [styles.toastContainer, {
maxWidth: dims.width / 10 * 9,
backgroundColor
}, style]
}, icon ? /*#__PURE__*/React.createElement(View, {
style: styles.iconContainer
}, icon) : null, /*#__PURE__*/React.isValidElement(message) ? message : /*#__PURE__*/React.createElement(Text, {
style: [styles.message, textStyle]
}, message))));
};
const styles = StyleSheet.create({
container: {
width: "100%",
alignItems: "center"
},
toastContainer: {
paddingHorizontal: 12,
paddingVertical: 12,
borderRadius: 5,
marginVertical: 5,
flexDirection: "row",
alignItems: "center",
overflow: "hidden"
},
message: {
color: "#fff",
fontWeight: "500"
},
iconContainer: {
marginRight: 5
}
});
export default Toast;
//# sourceMappingURL=toast.js.map