/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Modal
* @flow
*/
'use strict';
const AppContainer = require('AppContainer');
const I18nManager = require('I18nManager');
const Platform = require('Platform');
const React = require('React');
const StyleSheet = require('StyleSheet');
const View = require('View');
const deprecatedPropType = require('deprecatedPropType');
const requireNativeComponent = require('requireNativeComponent');
const RCTModalHostView = requireNativeComponent('RCTModalHostView', null);
const PropTypes = React.PropTypes;
/**
* The Modal component is a simple way to present content above an enclosing view.
*
* _Note: If you need more control over how to present modals over the rest of your app,
* then consider using a top-level Navigator._
*
* ```javascript
* import React, { Component } from 'react';
* import { Modal, Text, TouchableHighlight, View } from 'react-native';
*
* class ModalExample extends Component {
*
* state = {
* modalVisible: false,
* }
*
* setModalVisible(visible) {
* this.setState({modalVisible: visible});
* }
*
* render() {
* return (
*
* {alert("Modal has been closed.")}}
* >
*
*
* Hello World!
*
* {
* this.setModalVisible(!this.state.modalVisible)
* }}>
* Hide Modal
*
*
*
*
*
*
* {
* this.setModalVisible(true)
* }}>
* Show Modal
*
*
*
* );
* }
* }
* ```
*/
class Modal extends React.Component {
static propTypes = {
/**
* The `animationType` prop controls how the modal animates.
*
* - `slide` slides in from the bottom
* - `fade` fades into view
* - `none` appears without an animation
*/
animationType: PropTypes.oneOf(['none', 'slide', 'fade']),
/**
* The `transparent` prop determines whether your modal will fill the entire view. Setting this to `true` will render the modal over a transparent background.
*/
transparent: PropTypes.bool,
/**
* The `hardwareAccelerated` prop controls whether to force hardware acceleration for the underlying window.
* @platform android
*/
hardwareAccelerated: PropTypes.bool,
/**
* The `visible` prop determines whether your modal is visible.
*/
visible: PropTypes.bool,
/**
* The `onRequestClose` callback is called when the user taps the hardware back button.
* @platform android
*/
onRequestClose: Platform.OS === 'android' ? PropTypes.func.isRequired : PropTypes.func,
/**
* The `onShow` prop allows passing a function that will be called once the modal has been shown.
*/
onShow: PropTypes.func,
animated: deprecatedPropType(
PropTypes.bool,
'Use the `animationType` prop instead.'
),
/**
* The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations.
* On iOS, the modal is still restricted by what's specified in your app's Info.plist's UISupportedInterfaceOrientations field.
* @platform ios
*/
supportedOrientations: PropTypes.arrayOf(PropTypes.oneOf(['portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right'])),
/**
* The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed.
* The orientation provided is only 'portrait' or 'landscape'. This callback is also called on initial render, regardless of the current orientation.
* @platform ios
*/
onOrientationChange: PropTypes.func,
};
static defaultProps = {
visible: true,
hardwareAccelerated: false,
};
static contextTypes = {
rootTag: React.PropTypes.number,
};
render(): ?React.Element {
if (this.props.visible === false) {
return null;
}
const containerStyles = {
backgroundColor: this.props.transparent ? 'transparent' : 'white',
};
let animationType = this.props.animationType;
if (!animationType) {
// manually setting default prop here to keep support for the deprecated 'animated' prop
animationType = 'none';
if (this.props.animated) {
animationType = 'slide';
}
}
const innerChildren = __DEV__ ?
(
{this.props.children}
) :
this.props.children;
return (
{innerChildren}
);
}
// We don't want any responder events bubbling out of the modal.
_shouldSetResponder(): boolean {
return true;
}
}
const side = I18nManager.isRTL ? 'right' : 'left';
const styles = StyleSheet.create({
modal: {
position: 'absolute',
},
container: {
position: 'absolute',
[side] : 0,
top: 0,
}
});
module.exports = Modal;