Skip to content

Instantly share code, notes, and snippets.

@bogoslavskiy
Created November 28, 2018 17:21
Show Gist options
  • Save bogoslavskiy/784ce1acefe0b9bf638b675826d43b5c to your computer and use it in GitHub Desktop.
Save bogoslavskiy/784ce1acefe0b9bf638b675826d43b5c to your computer and use it in GitHub Desktop.
import React, { Component } from "react";
import {
StyleSheet,
Text,
TouchableOpacity,
View,
ScrollView
} from "react-native";
import Modal from "react-native-modal";
import { Viewport, getStatusBarHeight } from '../utils';
import { MaterialIcons, Ionicons } from '@expo/vector-icons';
export default class SwipeModal extends Component {
state = {
scrollOffset: 0,
contentHeight: 0,
};
handleOnScroll = event => {
this.setState({
scrollOffset: event.nativeEvent.contentOffset.y
});
};
handleScrollTo = p => {
if (this.scrollViewRef) {
this.scrollViewRef.scrollTo(p);
}
};
setHeightContent = (ev) => {
this.setState({ contentHeight: ev.nativeEvent.layout.height });
};
getHeightModal = () => {
return Viewport.height - getStatusBarHeight() - 45;
};
render() {
let {
contentContainerStyle,
wrapContentInScrollView,
isVisible,
onHide,
title,
height
} = this.props;
const { scrollOffset, contentHeight } = this.state;
if(!height) {
height = this.getHeightModal();
}
if(contentHeight != 0 && (contentHeight + 50) < height) {
//wrapContentInScrollView = false;
}
let propsForScrollView = wrapContentInScrollView ? {
scrollTo: this.handleScrollTo,
scrollOffset: scrollOffset,
scrollOffsetMax: (contentHeight - height),
} : {};
return (
<Modal
isVisible={isVisible}
onSwipe={onHide}
onBackdropPress={onHide}
swipeDirection="down"
backdropOpacity={0.5}
hideModalContentWhileAnimating={true}
style={styles.modalWrapper}
{...propsForScrollView}
>
<View style={[
styles.modalContent,
{height: height, paddingTop: 50},
contentContainerStyle || {}
]}>
<View style={styles.header}>
<View style={styles.swipeIcon} />
<TouchableOpacity onPress={onHide} style={styles.closeContainer}>
<MaterialIcons
name='close'
size={18}
style={styles.iconClose}
color='#fff'
/>
</TouchableOpacity>
<Text style={styles.title}>
{title}
</Text>
</View>
{wrapContentInScrollView ?
<View>
<ScrollView
ref={ref => (this.scrollViewRef = ref)}
onScroll={this.handleOnScroll}
scrollEventThrottle={16}
>
<View onLayout={this.setHeightContent}>
{this.props.renderContent()}
</View>
</ScrollView>
</View>
:
<View>
{this.props.renderContent()}
</View>
}
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
header: {
position: 'absolute',
top: 0,
left: 0,
zIndex: 1,
backgroundColor: '#f4f4f4',
width: '100%',
height: 50,
padding: 5,
alignItems: 'center',
borderBottomWidth: 1.5,
borderBottomColor: '#eee',
},
swipeIcon: {
width: 40,
height: 4,
backgroundColor: '#c7c7c7',
borderRadius: 20,
},
closeContainer: {
position: 'absolute',
right: 15,
top: 12,
backgroundColor: '#c7c7c7',
borderRadius: 50,
padding: 4,
},
title: {
color: '#060606',
fontSize: 16,
marginTop: 8,
},
modalWrapper: {
justifyContent: "flex-end",
margin: 0
},
modalContent: {
borderTopLeftRadius: 10,
borderTopRightRadius: 10,
overflow: 'hidden',
backgroundColor: '#e9e9ee'
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment