UNPKG

react-native-modal

Version:
202 lines (155 loc) 10.2 kB
# react-native-modal [![npm version](https://badge.fury.io/js/react-native-modal.svg)](https://badge.fury.io/js/react-native-modal) [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier) An enhanced, animated and customizable react-native modal. ## Features * Smooth enter/exit animations * Plain simple and flexible APIs * Customizable backdrop opacity, color and timing * Listeners for the modal animations ending * Resize itself correctly on device rotation * Swipeable ## Demo <p align="center"> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-tips/master/imgs/modal.gif" height="300" /> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-modal-datetime-picker/master/extras/datetimepicker-ios.gif" height="300" /> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-animated-modal/master/extras/example-modal.gif" height="300" /> </p> ## Setup This library is available on npm, install it with: `npm install --save react-native-modal` or `yarn add react-native-modal`. ## Usage Since react-native-modal is an extension of the original react native modal, it works in a similar fashion [react-native original modal](https://facebook.github.io/react-native/docs/modal.html). 1. Import react-native-modal: ```javascript import Modal from "react-native-modal"; ``` 2. Create a modal and nest its content inside of it: ```javascript render () { return ( <View> <Modal> <View style={{ flex: 1 }}> <Text>I am the modal content!</Text> </View> </Modal> </View> ) } ``` 3. Then simply show it by setting the `isVisible` prop to true: ```javascript render () { return ( <View> <Modal isVisible={true}> <View style={{ flex: 1 }}> <Text>I am the modal content!</Text> </View> </Modal> </View> ) } ``` The `isVisible` prop is the only prop you'll really need to make the modal work: you should control this prop value by saving it in your state and setting it to `true` or `false` when needed. ## A complete example The following example consists in a component (`ModalTester`) with a button and a modal. The modal is controlled by the `isModalVisible` state variable and it is initially hidden, since its value is `false`. Pressing the button sets `isModalVisible` to true, making the modal visible. Inside the modal there is another button that, when pressed, sets `isModalVisible` to false, hiding the modal. ```javascript import React, { Component } from "react"; import { Text, TouchableOpacity, View } from "react-native"; import Modal from "react-native-modal"; export default class ModalTester extends Component { state = { isModalVisible: false }; _toggleModal = () => this.setState({ isModalVisible: !this.state.isModalVisible }); render() { return ( <View style={{ flex: 1 }}> <TouchableOpacity onPress={this._toggleModal}> <Text>Show Modal</Text> </TouchableOpacity> <Modal isVisible={this.state.isModalVisible}> <View style={{ flex: 1 }}> <Text>Hello!</Text> <TouchableOpacity onPress={this._toggleModal}> <Text>Hide me!</Text> </TouchableOpacity> </View> </Modal> </View> ); } } ``` For a more complex example take a look at the `/example` directory. ## Available props | Name | Type | Default | Description | | ------------------------------ | ---------------- | -------------- | -------------------------------------------------------------------------------------------- | | animationIn | string or object | 'slideInUp' | Modal show animation | | animationInTiming | number | 300 | Timing for the modal show animation (in ms) | | animationOut | string or object | 'slideOutDown' | Modal hide animation | | animationOutTiming | number | 300 | Timing for the modal hide animation (in ms) | | avoidKeyboard | bool | false | Move the modal up if the keyboard is open | | backdropColor | string | 'black' | The backdrop background color | | backdropOpacity | number | 0.70 | The backdrop opacity when the modal is visible | | backdropTransitionInTiming | number | 300 | The backdrop show timing (in ms) | | backdropTransitionOutTiming | number | 300 | The backdrop hide timing (in ms) | | children | node | **REQUIRED** | The modal content | | isVisible | bool | **REQUIRED** | Show the modal? | | onBackButtonPress | func | () => null | Called when the Android back button is pressed | | onBackdropPress | func | () => null | Called when the backdrop is pressed | | onModalHide | func | () => null | Called when the modal is completely hidden | | onModalShow | func | () => null | Called when the modal is completely visible | | onSwipe | func | null | Called when the `swipeThreshold` has been reached | | swipeThreshold | number | 100 | Swiping threshold that when reached calls `onSwipe` | | swipeDirection | string | null | Defines the direction where the modal can be swiped (can be 'up', 'down', 'left, or 'right') | | useNativeDriver | bool | false | Defines if animations should use native driver | | hideModalContentWhileAnimating | bool | false | Enhances the performance by hiding the modal content until the animations complete | | style | any | null | Style applied to the modal | ## Frequently Asked Questions ### The component is not working as expected Under the hood `react-native-modal` uses react-native original [Modal component](https://facebook.github.io/react-native/docs/modal.html). Before reporting a bug, try swapping `react-native-modal` with react-native original Modal component and, if the issue persists, check if it has already been reported as a [react-native issue](https://github.com/facebook/react-native/issues). ### How can I hide the modal by pressing outside of its content? The prop `onBackdropPress` allows you to handle this situation: ```javascript <Modal isVisible={this.state.isVisible} onBackdropPress={() => this.setState({ isVisible: false })} > <View style={{ flex: 1 }}> <Text>I am the modal content!</Text> </View> </Modal> ``` ### How can I hide the modal by swiping it? The prop `onSwipe` allows you to handle this situation (remember to set `swipeDirection` too!): ```javascript <Modal isVisible={this.state.isVisible} onSwipe={() => this.setState({ isVisible: false })} swipeDirection="left" > <View style={{ flex: 1 }}> <Text>I am the modal content!</Text> </View> </Modal> ``` ### The modal flashes in a weird way when animating Unfortunately this is a [know issue](https://github.com/react-native-community/react-native-modal/issues/92) that happens when `useNativeDriver=true` and must still be solved. In the meanwhile as a workaround you can set the `hideModalContentWhileAnimating` prop to `true`: this seems to solve the issue. Also, do not assign a `backgroundColor` property directly to the Modal. Prefer to set it on the child container. ### The modal background doesn't animate properly Are you sure you named the `isVisible` prop correctly? Make sure it is spelled correctly: `isVisible`, not `visible`. ### The modal doesn't change orientation Add a `supportedOrientations={['portrait', 'landscape']}` prop to the component, as described [in the React Native documentation](https://facebook.github.io/react-native/docs/modal.html#supportedorientations). ## Available animations Take a look at [react-native-animatable](https://github.com/oblador/react-native-animatable) to see the dozens of animations available out-of-the-box. You can also pass in custom animation definitions and have them automatically register with react-native-animatable. For more information on creating custom animations, see the react-native-animatable [animation definition schema](https://github.com/oblador/react-native-animatable#animation-definition-schema). ## Acknowledgements Thanks [@oblador](https://github.com/oblador) for react-native-animatable, [@brentvatne](https://github.com/brentvatne) for the npm namespace and to anyone who contributed to this library! Pull requests, feedbacks and suggestions are welcome!