import React, { useState, useRef, useEffect } from 'react';
import { View, Text, Button, Modal, StyleSheet, Animated, TouchableOpacity, Dimensions } from 'react-native';
const screenHeight = Dimensions.get('window').height;
export default function ModalBottomSheetDemo() {
const [modalVisible, setModalVisible] = useState(false);
const [bottomSheetVisible, setBottomSheetVisible] = useState(false);
const slideAnim = useRef(new Animated.Value(screenHeight)).current;
useEffect(() => {
if (bottomSheetVisible) {
Animated.timing(slideAnim, {
toValue: screenHeight - 250,
duration: 300,
useNativeDriver: false
}).start();
} else {
Animated.timing(slideAnim, {
toValue: screenHeight,
duration: 300,
useNativeDriver: false
}).start();
}
}, [bottomSheetVisible, slideAnim]);
return (
<View style={styles.container}>
<Button title="Open Modal" onPress={() => setModalVisible(true)} />
<View style={{ height: 20 }} />
<Button title="Open Bottom Sheet" onPress={() => setBottomSheetVisible(true)} />
<Modal
visible={modalVisible}
transparent={true}
animationType="fade"
onRequestClose={() => setModalVisible(false)}
>
<View style={styles.modalBackground}>
<View style={styles.modalBox}>
<Text style={styles.modalText}>This is a modal</Text>
<Button title="Close" onPress={() => setModalVisible(false)} />
</View>
</View>
</Modal>
<Animated.View style={[styles.bottomSheet, { top: slideAnim }]}>
<Text style={styles.sheetText}>This is a bottom sheet</Text>
<TouchableOpacity style={styles.closeButton} onPress={() => setBottomSheetVisible(false)}>
<Text style={styles.closeButtonText}>Close</Text>
</TouchableOpacity>
</Animated.View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: 20,
backgroundColor: '#fff'
},
modalBackground: {
flex: 1,
backgroundColor: 'rgba(0,0,0,0.5)',
justifyContent: 'center',
alignItems: 'center'
},
modalBox: {
width: 300,
padding: 20,
backgroundColor: 'white',
borderRadius: 10,
alignItems: 'center'
},
modalText: {
fontSize: 18,
marginBottom: 15
},
bottomSheet: {
position: 'absolute',
left: 0,
width: '100%',
height: 250,
backgroundColor: 'white',
borderTopLeftRadius: 15,
borderTopRightRadius: 15,
padding: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: -3 },
shadowOpacity: 0.3,
shadowRadius: 4,
elevation: 5
},
sheetText: {
fontSize: 18,
marginBottom: 20
},
closeButton: {
backgroundColor: '#2196F3',
paddingVertical: 10,
borderRadius: 5,
alignItems: 'center'
},
closeButtonText: {
color: 'white',
fontSize: 16
}
});We use React Native's Modal component to show a modal in the center with a semi-transparent dark background. The modal box contains a message and a close button that sets modalVisible to false.
For the bottom sheet, we use an Animated.View that slides up from the bottom. We animate its top position from off-screen (screen height) to visible (screen height - 250). The bottom sheet has a message and a close button that hides it by setting bottomSheetVisible to false.
This approach keeps UI simple and uses React Native's built-in components and animation for smooth transitions.