Skip to content

Instantly share code, notes, and snippets.

@mmazzarolo
Created May 25, 2016 15:35
Show Gist options
  • Save mmazzarolo/1bddd15effd68b9eb0dbebfcfc1a9793 to your computer and use it in GitHub Desktop.
Save mmazzarolo/1bddd15effd68b9eb0dbebfcfc1a9793 to your computer and use it in GitHub Desktop.
React-Native animated modal (supports dismiss on backdrop touch and Android back button )
import React, { Component, PropTypes } from 'react'
import { Dimensions, Modal, StyleSheet } from 'react-native'
import { View } from 'react-native-animatable'
const DEVICE_WIDTH = Dimensions.get('window').width
const DEVICE_HEIGHT = Dimensions.get('window').height
const DEFAULT_COLOR = '#001a33'
export default class CustomModal extends Component {
static propTypes = {
visible: PropTypes.bool,
children: PropTypes.node,
backdropBackground: PropTypes.string
}
static defaultProps = {
visible: false,
backdropBackground: DEFAULT_COLOR
}
constructor (props) {
super(props)
this.state = {
visible: false
}
}
componentWillReceiveProps (nextProps) {
if (!this.state.visible && nextProps.visible) {
this.setState({ visible: true })
}
}
componentDidUpdate (prevProps, prevState) {
// On modal open request slide the view up and fade in the backdrop
if (this.state.visible && !prevState.visible) {
this.open()
// On modal close request slide the view down and fade out the backdrop
} else if (!this.props.visible && prevProps.visible) {
this.close()
}
}
open = () => {
this.refs.backdrop.transitionTo({ opacity: 0.70 })
this.refs.content.slideInUp(300)
}
close = () => {
this.refs.backdrop.transitionTo({ opacity: 0 })
this.refs.content.slideOutDown(300)
.then(() => this.setState({ visible: false }))
}
render () {
const { children, backdropBackground } = this.props
const { visible } = this.state
return (
<Modal
transparent={true}
animationType={'none'}
{...this.props}
visible={visible}
onRequestClose={this.close}
>
<View ref={'backdrop'} style={[styles.backdrop, { backgroundColor: backdropBackground }]} />
<View style={{ flex: 1 }} ref={'content'} onStartShouldSetResponder={this.close}>
{children}
</View>
</Modal>
)
}
}
const styles = StyleSheet.create({
backdrop: {
top: 0,
bottom: 0,
left: 0,
right: 0,
height: DEVICE_HEIGHT,
width: DEVICE_WIDTH,
position: 'absolute',
opacity: 0
}
})
@mmazzarolo
Copy link
Author

<CustomModal visible={show the modal?}>
  <View>
    {my modal content}
  <View>
</CustomModal>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment