UNPKG

react-native-modern-elements

Version:

A modern, customizable UI component library for React Native

122 lines (121 loc) 5.23 kB
import React, { memo, useEffect } from "react"; import { BackHandler, Modal, Platform, StatusBar, StyleSheet, TouchableWithoutFeedback, } from "react-native"; import Animated, { useAnimatedStyle, useSharedValue, withSpring, } from "react-native-reanimated"; const Modals = ({ visible, children, animation, onClose, modalContainer, StatusBarColors, barStyle, }) => { const [showModal, setShowModal] = React.useState(visible); const translateX = useSharedValue(0); const translateY = useSharedValue(500); const scaleValue = useSharedValue(0); // Staus bar colors useEffect(() => { if (visible) { if (Platform.OS === "android") { StatusBar.setBackgroundColor("#797777", true); } StatusBar.setBarStyle("light-content", true); } else { if (Platform.OS === "android") { StatusBar.setBackgroundColor(StatusBarColors, true); } StatusBar.setBarStyle(barStyle, true); } }, [visible, StatusBarColors, barStyle]); // open and close animation useEffect(() => { if (visible) { setShowModal(true); // Opening animations if (animation === "LeftToCenterCloseToRight") { translateX.value = -500; translateX.value = withSpring(0, { damping: 10 }); } else if (animation === "center") { scaleValue.value = 0; scaleValue.value = withSpring(1, { damping: 14 }); } else if (animation === "BottomToCenterCloseToBottom") { translateY.value = 500; translateY.value = withSpring(0, { damping: 10 }); } else if (animation === "RightToCenterCloseToLeft") { translateX.value = 500; // start from right translateX.value = withSpring(0, { damping: 10 }); } else if (animation === "LeftToCenterCloseToLeft") { translateX.value = -500; translateX.value = withSpring(0, { damping: 10 }); } else if (animation === "RightToCenterCloseToRight") { translateX.value = 500; translateX.value = withSpring(0, { damping: 10 }); } const backHandler = BackHandler.addEventListener("hardwareBackPress", () => { onClose(); return true; }); return () => backHandler.remove(); } else { // Closing animations if (animation === "LeftToCenterCloseToRight") { translateX.value = withSpring(500, { damping: 10 }); } else if (animation === "center") { scaleValue.value = withSpring(0, { damping: 15 }); } else if (animation === "BottomToCenterCloseToBottom") { translateY.value = withSpring(700, { damping: 20 }); } else if (animation === "RightToCenterCloseToLeft") { translateX.value = withSpring(-500, { damping: 10 }); // close to left } else if (animation === "LeftToCenterCloseToLeft") { translateX.value = withSpring(-500, { damping: 10 }); } else if (animation === "RightToCenterCloseToRight") { translateX.value = withSpring(500, { damping: 10 }); } setTimeout(() => setShowModal(false), 350); } }, [visible, animation, onClose, scaleValue, translateX, translateY]); const modalStyle = useAnimatedStyle(() => { let transformStyles = []; if (animation === "center") { transformStyles = [{ scale: scaleValue.value }]; } else if (animation === "LeftToCenterCloseToRight" || animation === "RightToCenterCloseToLeft" || animation === "LeftToCenterCloseToLeft" || animation === "RightToCenterCloseToRight") { transformStyles = [{ translateX: translateX.value }]; } else if (animation === "BottomToCenterCloseToBottom") { transformStyles = [{ translateY: translateY.value }]; } return { transform: transformStyles }; }); return (React.createElement(Modal, { transparent: true, visible: showModal, onRequestClose: onClose }, React.createElement(TouchableWithoutFeedback, { onPress: onClose }, React.createElement(Animated.View, { style: styles.modalBackground }, React.createElement(TouchableWithoutFeedback, null, React.createElement(Animated.View, { style: [styles.modalContainer, modalStyle, modalContainer] }, children)))))); }; const styles = StyleSheet.create({ modalBackground: { flex: 1, backgroundColor: "rgba(0, 0, 0, 0.5)", justifyContent: "center", alignItems: "center", overflow: "hidden", }, modalContainer: { width: "80%", backgroundColor: "white", paddingHorizontal: 20, paddingVertical: 30, borderRadius: 20, elevation: 20, }, }); export default memo(Modals);