react-native-modal
Advanced tools
Comparing version 12.1.0 to 13.0.0
import * as React from 'react'; | ||
import { Animated, PanResponderGestureState, PanResponderInstance, StyleProp, ViewStyle, ViewProps } from 'react-native'; | ||
import { Animated, EmitterSubscription, PanResponderGestureState, PanResponderInstance, StyleProp, ViewStyle, ViewProps } from 'react-native'; | ||
import * as PropTypes from 'prop-types'; | ||
@@ -151,2 +151,3 @@ import * as animatable from 'react-native-animatable'; | ||
panResponder: OrNull<PanResponderInstance>; | ||
didUpdateDimensionsEmitter: OrNull<EmitterSubscription>; | ||
interactionHandle: OrNull<number>; | ||
@@ -153,0 +154,0 @@ constructor(props: ModalProps); |
@@ -67,2 +67,3 @@ import * as React from 'react'; | ||
this.panResponder = null; | ||
this.didUpdateDimensionsEmitter = null; | ||
this.interactionHandle = null; | ||
@@ -452,3 +453,3 @@ this.getDeviceHeight = () => this.props.deviceHeight || this.state.deviceHeight; | ||
} | ||
DeviceEventEmitter.addListener('didUpdateDimensions', this.handleDimensionsUpdate); | ||
this.didUpdateDimensionsEmitter = DeviceEventEmitter.addListener('didUpdateDimensions', this.handleDimensionsUpdate); | ||
if (this.state.isVisible) { | ||
@@ -461,3 +462,5 @@ this.open(); | ||
BackHandler.removeEventListener('hardwareBackPress', this.onBackButtonPress); | ||
DeviceEventEmitter.removeListener('didUpdateDimensions', this.handleDimensionsUpdate); | ||
if (this.didUpdateDimensionsEmitter) { | ||
this.didUpdateDimensionsEmitter.remove(); | ||
} | ||
if (this.interactionHandle) { | ||
@@ -464,0 +467,0 @@ InteractionManager.clearInteractionHandle(this.interactionHandle); |
{ | ||
"name": "react-native-modal", | ||
"version": "12.1.0", | ||
"version": "13.0.0", | ||
"description": "An enhanced React Native modal", | ||
@@ -82,3 +82,3 @@ "main": "dist/index.js", | ||
"react": "*", | ||
"react-native": "*" | ||
"react-native": ">=0.65.0" | ||
}, | ||
@@ -85,0 +85,0 @@ "jest": { |
149
README.md
@@ -10,6 +10,8 @@ 🚧 We're looking for maintainers and contributors! See [#414](https://github.com/react-native-community/react-native-modal/issues/414) | ||
An enhanced, animated and customizable react-native modal. | ||
> If you're new to the React Native world, please notice that React Native itself offers a [<Modal /> component that works out-of-the-box](https://reactnative.dev/docs/modal). | ||
The goal of `react-native-modal` is expanding the original react-native `Modal` component by adding animations and styles customization options while still providing a plain-simple API. | ||
An enhanced, animated, customizable React Native modal. | ||
The goal of `react-native-modal` is expanding the original React Native `<Modal>` component by adding animations, style customization options, and new features, while still providing a simple API. | ||
<p align="center"> | ||
@@ -35,11 +37,11 @@ <img src="/.github/images/example-modal.gif" height="500" /> | ||
Since react-native-modal is an extension of the original react native modal, it works in a similar fashion [react-native original modal](https://reactnative.dev/docs/modal.html). | ||
Since `react-native-modal` is an extension of the [original React Native modal](https://reactnative.dev/docs/modal.html), it works in a similar fashion. | ||
1. Import react-native-modal: | ||
1. Import `react-native-modal`: | ||
```javascript | ||
import Modal from 'react-native-modal'; | ||
import Modal from "react-native-modal"; | ||
``` | ||
2. Create a modal and nest its content inside of it: | ||
2. Create a `<Modal>` component and nest its content inside of it: | ||
@@ -51,3 +53,3 @@ ```javascript | ||
<Modal> | ||
<View style={{flex: 1}}> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -61,3 +63,3 @@ </View> | ||
3. Then simply show it by setting the `isVisible` prop to true: | ||
3. Then, show the modal by setting the `isVisible` prop to `true`: | ||
@@ -69,3 +71,3 @@ ```javascript | ||
<Modal isVisible={true}> | ||
<View style={{flex: 1}}> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -89,5 +91,5 @@ </View> | ||
```javascript | ||
import React, {useState} from 'react'; | ||
import {Button, Text, View} from 'react-native'; | ||
import Modal from 'react-native-modal'; | ||
import React, { useState } from "react"; | ||
import { Button, Text, View } from "react-native"; | ||
import Modal from "react-native-modal"; | ||
@@ -102,7 +104,7 @@ function ModalTester() { | ||
return ( | ||
<View style={{flex: 1}}> | ||
<View style={{ flex: 1 }}> | ||
<Button title="Show modal" onPress={toggleModal} /> | ||
<Modal isVisible={isModalVisible}> | ||
<View style={{flex: 1}}> | ||
<View style={{ flex: 1 }}> | ||
<Text>Hello!</Text> | ||
@@ -124,42 +126,42 @@ | ||
| 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 | | ||
| coverScreen | bool | true | Will use RN `Modal` component to cover the entire screen wherever the modal is mounted in the component hierarchy | | ||
| hasBackdrop | bool | true | Render the backdrop | | ||
| 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) | | ||
| customBackdrop | node | null | The custom backdrop element | | ||
| children | node | **REQUIRED** | The modal content | | ||
| deviceHeight | number | null | Device height (useful on devices that can hide the navigation bar) | | ||
| deviceWidth | number | null | Device width (useful on devices that can hide the navigation bar) | | ||
| 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 | | ||
| onModalWillHide | func | () => null | Called before the modal hide animation begins | | ||
| onModalHide | func | () => null | Called when the modal is completely hidden | | ||
| onModalWillShow | func | () => null | Called before the modal show animation begins | | ||
| onModalShow | func | () => null | Called when the modal is completely visible | | ||
| onSwipeStart | func | () => null | Called when the swipe action started | | ||
| onSwipeMove | func | (percentageShown) => null | Called on each swipe event | | ||
| onSwipeComplete | func | ({ swipingDirection }) => null | Called when the `swipeThreshold` has been reached | | ||
| onSwipeCancel | func | () => null | Called when the `swipeThreshold` has not been reached | | ||
| panResponderThreshold | number | 4 | The threshold for when the panResponder should pick up swipe events | | ||
| scrollOffset | number | 0 | When > 0, disables swipe-to-close, in order to implement scrollable content | | ||
| scrollOffsetMax | number | 0 | Used to implement overscroll feel when content is scrollable. See `/example` directory | | ||
| scrollTo | func | null | Used to implement scrollable modal. See `/example` directory for reference on how to use it | | ||
| scrollHorizontal | bool | false | Set to true if your scrollView is horizontal (for a correct scroll handling) | | ||
| swipeThreshold | number | 100 | Swiping threshold that when reached calls `onSwipeComplete` | | ||
| swipeDirection | string or array | null | Defines the direction where the modal can be swiped. Can be 'up', 'down', 'left, or 'right', or a combination of them like `['up','down']` | | ||
| useNativeDriver | bool | false | Defines if animations should use native driver | | ||
| useNativeDriverForBackdrop | bool | null | Defines if animations for backdrop should use native driver (to avoid flashing on android) | | ||
| hideModalContentWhileAnimating | bool | false | Enhances the performance by hiding the modal content until the animations complete | | ||
| propagateSwipe | bool or func | false | Allows swipe events to propagate to children components (eg a ScrollView inside a modal) | | ||
| style | any | null | Style applied to the modal | | ||
| 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 | | ||
| `coverScreen` | `bool` | `true` | Will use RN `Modal` component to cover the entire screen wherever the modal is mounted in the component hierarchy | | ||
| `hasBackdrop` | `bool` | `true` | Render the backdrop | | ||
| `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) | | ||
| `customBackdrop` | `node` | `null` | The custom backdrop element | | ||
| `children` | `node` | **REQUIRED** | The modal content | | ||
| `deviceHeight` | `number` | `null` | Device height (useful on devices that can hide the navigation bar) | | ||
| `deviceWidth` | `number` | `null` | Device width (useful on devices that can hide the navigation bar) | | ||
| `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 | | ||
| `onModalWillHide` | `func` | `() => null` | Called before the modal hide animation begins | | ||
| `onModalHide` | `func` | `() => null` | Called when the modal is completely hidden | | ||
| `onModalWillShow` | `func` | `() => null` | Called before the modal show animation begins | | ||
| `onModalShow` | `func` | `() => null` | Called when the modal is completely visible | | ||
| `onSwipeStart` | `func` | `() => null` | Called when the swipe action started | | ||
| `onSwipeMove` | `func` | `(percentageShown) => null` | Called on each swipe event | | ||
| `onSwipeComplete` | `func` | `({ swipingDirection }) => null` | Called when the `swipeThreshold` has been reached | | ||
| `onSwipeCancel` | `func` | `() => null` | Called when the `swipeThreshold` has not been reached | | ||
| `panResponderThreshold` | `number` | `4` | The threshold for when the panResponder should pick up swipe events | | ||
| `scrollOffset` | `number` | `0` | When > 0, disables swipe-to-close, in order to implement scrollable content | | ||
| `scrollOffsetMax` | `number` | `0` | Used to implement overscroll feel when content is scrollable. See `/example` directory | | ||
| `scrollTo` | `func` | `null` | Used to implement scrollable modal. See `/example` directory for reference on how to use it | | ||
| `scrollHorizontal` | `bool` | `false` | Set to true if your scrollView is horizontal (for a correct scroll handling) | | ||
| `swipeThreshold` | `number` | `100` | Swiping threshold that when reached calls `onSwipeComplete` | | ||
| `swipeDirection` | `string` or `array` | `null` | Defines the direction where the modal can be swiped. Can be 'up', 'down', 'left, or 'right', or a combination of them like `['up','down']` | | ||
| `useNativeDriver` | `bool` | `false` | Defines if animations should use native driver | | ||
| `useNativeDriverForBackdrop` | `bool` | `null` | Defines if animations for backdrop should use native driver (to avoid flashing on android) | | ||
| `hideModalContentWhileAnimating` | `bool` | `false` | Enhances the performance by hiding the modal content until the animations complete | | ||
| `propagateSwipe` | `bool` or `func` | `false` | Allows swipe events to propagate to children components (eg a ScrollView inside a modal) | | ||
| `style` | `any` | `null` | Style applied to the modal | | ||
@@ -180,8 +182,8 @@ ## Frequently Asked Questions | ||
```javascript | ||
const deviceWidth = Dimensions.get('window').width; | ||
const deviceWidth = Dimensions.get("window").width; | ||
const deviceHeight = | ||
Platform.OS === 'ios' | ||
? Dimensions.get('window').height | ||
: require('react-native-extra-dimensions-android').get( | ||
'REAL_WINDOW_HEIGHT', | ||
Platform.OS === "ios" | ||
? Dimensions.get("window").height | ||
: require("react-native-extra-dimensions-android").get( | ||
"REAL_WINDOW_HEIGHT" | ||
); | ||
@@ -196,4 +198,5 @@ | ||
deviceWidth={deviceWidth} | ||
deviceHeight={deviceHeight}> | ||
<View style={{flex: 1}}> | ||
deviceHeight={deviceHeight} | ||
> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -213,4 +216,5 @@ </View> | ||
isVisible={isModalVisible} | ||
onBackdropPress={() => setModalVisible(false)}> | ||
<View style={{flex: 1}}> | ||
onBackdropPress={() => setModalVisible(false)} | ||
> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -229,4 +233,5 @@ </View> | ||
onSwipeComplete={() => setModalVisible(false)} | ||
swipeDirection="left"> | ||
<View style={{flex: 1}}> | ||
swipeDirection="left" | ||
> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -277,3 +282,3 @@ </View> | ||
```js | ||
<Modal style={{margin: 0}}>...</Modal> | ||
<Modal style={{ margin: 0 }}>...</Modal> | ||
``` | ||
@@ -302,4 +307,4 @@ | ||
```javascript | ||
<Modal isVisible={isModalVisible} customBackdrop={<View style={{flex: 1}} />}> | ||
<View style={{flex: 1}}> | ||
<Modal isVisible={isModalVisible} customBackdrop={<View style={{ flex: 1 }} />}> | ||
<View style={{ flex: 1 }}> | ||
<Text>I am the modal content!</Text> | ||
@@ -319,3 +324,3 @@ </View> | ||
<TouchableWithoutFeedback onPress={dismissModalHandler}> | ||
<View style={{flex: 1}} /> | ||
<View style={{ flex: 1 }} /> | ||
</TouchableWithoutFeedback> | ||
@@ -330,2 +335,8 @@ } | ||
## Alternatives | ||
- [React Native's own `<Modal>` component](https://reactnative.dev/docs/modal.html) | ||
- [React Native Paper `<Modal>` component](https://callstack.github.io/react-native-paper/modal.html) | ||
- [React Native Modalfy](https://github.com/colorfy-software/react-native-modalfy) | ||
## Acknowledgements | ||
@@ -332,0 +343,0 @@ |
72288
918
331