{"id":3946,"url":"https://github.com/react-native-modal/react-native-modal","last_synced_at":"2026-01-12T00:15:02.450Z","repository":{"id":37389410,"uuid":"69043435","full_name":"react-native-modal/react-native-modal","owner":"react-native-modal","description":"An enhanced, animated, customizable Modal for React Native.","archived":false,"fork":false,"pushed_at":"2025-04-05T04:17:25.000Z","size":15702,"stargazers_count":5568,"open_issues_count":65,"forks_count":648,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-05-12T04:07:42.305Z","etag":null,"topics":["android","animated","animation","backdrop","ios","modal","react","react-native"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-native-modal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-09-23T16:45:46.000Z","updated_at":"2025-05-11T22:51:26.000Z","dependencies_parsed_at":"2024-04-25T00:41:20.717Z","dependency_job_id":"30caa2ac-b652-408a-a4f6-7e6c0d88b0ad","html_url":"https://github.com/react-native-modal/react-native-modal","commit_stats":{"total_commits":430,"total_committers":94,"mean_commits":4.574468085106383,"dds":0.5651162790697675,"last_synced_commit":"6624b5abb326470820f9fedec8b3ecdb35520869"},"previous_names":["react-native-community/react-native-modal"],"tags_count":68,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-modal%2Freact-native-modal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-modal%2Freact-native-modal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-modal%2Freact-native-modal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-native-modal%2Freact-native-modal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-native-modal","download_url":"https://codeload.github.com/react-native-modal/react-native-modal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253672707,"owners_count":21945481,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","animated","animation","backdrop","ios","modal","react","react-native"],"created_at":"2024-01-05T20:16:56.179Z","updated_at":"2026-01-12T00:14:58.378Z","avatar_url":"https://github.com/react-native-modal.png","language":"TypeScript","funding_links":[],"categories":["Components","TypeScript","React Native","UI Components"],"sub_categories":["UI","Modals, Sheets \u0026 Overlays"],"readme":"### Announcements\n\n- 📣 We're looking for maintainers and contributors! See [#598](https://github.com/react-native-modal/react-native-modal/discussions/598)\n- 🙏 If you have a question, please [start a new discussion](https://github.com/react-native-modal/react-native-modal/discussions) instead of opening a new issue.\n\n# react-native-modal\n\n[![npm version](https://badge.fury.io/js/react-native-modal.svg)](https://badge.fury.io/js/react-native-modal)\n[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n\n\u003e If you're new to the React Native world, please notice that React Native itself offers a [\u003cModal /\u003e component that works out-of-the-box](https://reactnative.dev/docs/modal).\n\nAn enhanced, animated, customizable React Native modal.\n\nThe goal of `react-native-modal` is expanding the original React Native `\u003cModal\u003e` component by adding animations, style customization options, and new features, while still providing a simple API.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"/.github/images/example-modal.gif\" height=\"500\" /\u003e\n\u003c/p\u003e\n\n## Features\n\n- Smooth enter/exit animations\n- Plain simple and flexible APIs\n- Customizable backdrop opacity, color and timing\n- Listeners for the modal animations ending\n- Resize itself correctly on device rotation\n- Swipeable\n- Scrollable\n\n## Setup\n\nThis library is available on npm, install it with: `npm i react-native-modal` or `yarn add react-native-modal`.\n\n## Usage\n\nSince `react-native-modal` is an extension of the [original React Native modal](https://reactnative.dev/docs/modal.html), it works in a similar fashion.\n\n1.  Import `react-native-modal`:\n\n```javascript\nimport Modal from 'react-native-modal';\n```\n\n2.  Create a `\u003cModal\u003e` component and nest its content inside of it:\n\n```javascript\nfunction WrapperComponent() {\n  return (\n    \u003cView\u003e\n      \u003cModal\u003e\n        \u003cView style={{flex: 1}}\u003e\n          \u003cText\u003eI am the modal content!\u003c/Text\u003e\n        \u003c/View\u003e\n      \u003c/Modal\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\n3.  Then, show the modal by setting the `isVisible` prop to `true`:\n\n```javascript\nfunction WrapperComponent() {\n  return (\n    \u003cView\u003e\n      \u003cModal isVisible={true}\u003e\n        \u003cView style={{flex: 1}}\u003e\n          \u003cText\u003eI am the modal content!\u003c/Text\u003e\n        \u003c/View\u003e\n      \u003c/Modal\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\nThe `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 wrapper component state and setting it to `true` or `false` when needed.\n\n## A complete example\n\nThe following example consists in a component (`ModalTester`) with a button and a modal.\nThe modal is controlled by the `isModalVisible` state variable and it is initially hidden, since its value is `false`.  \nPressing the button sets `isModalVisible` to true, making the modal visible.  \nInside the modal there is another button that, when pressed, sets `isModalVisible` to false, hiding the modal.\n\n```javascript\nimport React, {useState} from 'react';\nimport {Button, Text, View} from 'react-native';\nimport Modal from 'react-native-modal';\n\nfunction ModalTester() {\n  const [isModalVisible, setModalVisible] = useState(false);\n\n  const toggleModal = () =\u003e {\n    setModalVisible(!isModalVisible);\n  };\n\n  return (\n    \u003cView style={{flex: 1}}\u003e\n      \u003cButton title=\"Show modal\" onPress={toggleModal} /\u003e\n\n      \u003cModal isVisible={isModalVisible}\u003e\n        \u003cView style={{flex: 1}}\u003e\n          \u003cText\u003eHello!\u003c/Text\u003e\n\n          \u003cButton title=\"Hide modal\" onPress={toggleModal} /\u003e\n        \u003c/View\u003e\n      \u003c/Modal\u003e\n    \u003c/View\u003e\n  );\n}\n\nexport default ModalTester;\n```\n\nFor a more complex example take a look at the `/example` directory.\n\n## Available props\n\n| Name                             | Type                 | Default                          | Description                                                                                                                                |\n| -------------------------------- | -------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |\n| `animationIn`                    | `string` or `object` | `\"slideInUp\"`                    | Modal show animation                                                                                                                       |\n| `animationInTiming`              | `number`             | `300`                            | Timing for the modal show animation (in ms)                                                                                                |\n| `animationOut`                   | `string` or `object` | `\"slideOutDown\"`                 | Modal hide animation                                                                                                                       |\n| `animationOutTiming`             | `number`             | `300`                            | Timing for the modal hide animation (in ms)                                                                                                |\n| `avoidKeyboard`                  | `bool`               | `false`                          | Move the modal up if the keyboard is open                                                                                                  |\n| `coverScreen`                    | `bool`               | `true`                           | Will use RN `Modal` component to cover the entire screen wherever the modal is mounted in the component hierarchy                          |\n| `hasBackdrop`                    | `bool`               | `true`                           | Render the backdrop                                                                                                                        |\n| `backdropColor`                  | `string`             | `\"black\"`                        | The backdrop background color                                                                                                              |\n| `backdropOpacity`                | `number`             | `0.70`                           | The backdrop opacity when the modal is visible                                                                                             |\n| `backdropTransitionInTiming`     | `number`             | `300`                            | The backdrop show timing (in ms)                                                                                                           |\n| `backdropTransitionOutTiming`    | `number`             | `300`                            | The backdrop hide timing (in ms)                                                                                                           |\n| `customBackdrop`                 | `node`               | `null`                           | The custom backdrop element                                                                                                                |\n| `children`                       | `node`               | **REQUIRED**                     | The modal content                                                                                                                          |\n| `deviceHeight`                   | `number`             | `null`                           | Device height (useful on devices that can hide the navigation bar)                                                                         |\n| `deviceWidth`                    | `number`             | `null`                           | Device width (useful on devices that can hide the navigation bar)                                                                          |\n| `isVisible`                      | `bool`               | **REQUIRED**                     | Show the modal?                                                                                                                            |\n| `onBackButtonPress`              | `func`               | `() =\u003e null`                     | Called when the Android back button is pressed                                                                                             |\n| `onBackdropPress`                | `func`               | `() =\u003e null`                     | Called when the backdrop is pressed                                                                                                        |\n| `onModalWillHide`                | `func`               | `() =\u003e null`                     | Called before the modal hide animation begins                                                                                              |\n| `onModalHide`                    | `func`               | `() =\u003e null`                     | Called when the modal is completely hidden                                                                                                 |\n| `onModalWillShow`                | `func`               | `() =\u003e null`                     | Called before the modal show animation begins                                                                                              |\n| `onModalShow`                    | `func`               | `() =\u003e null`                     | Called when the modal is completely visible                                                                                                |\n| `onSwipeStart`                   | `func`               | `() =\u003e null`                     | Called when the swipe action started                                                                                                       |\n| `onSwipeMove`                    | `func`               | `(percentageShown) =\u003e null`      | Called on each swipe event                                                                                                                 |\n| `onSwipeComplete`                | `func`               | `({ swipingDirection }) =\u003e null` | Called when the `swipeThreshold` has been reached                                                                                          |\n| `onSwipeCancel`                  | `func`               | `() =\u003e null`                     | Called when the `swipeThreshold` has not been reached                                                                                      |\n| `panResponderThreshold`          | `number`             | `4`                              | The threshold for when the panResponder should pick up swipe events                                                                        |\n| `scrollOffset`                   | `number`             | `0`                              | When \u003e 0, disables swipe-to-close, in order to implement scrollable content                                                                |\n| `scrollOffsetMax`                | `number`             | `0`                              | Used to implement overscroll feel when content is scrollable. See `/example` directory                                                     |\n| `scrollTo`                       | `func`               | `null`                           | Used to implement scrollable modal. See `/example` directory for reference on how to use it                                                |\n| `scrollHorizontal`               | `bool`               | `false`                          | Set to true if your scrollView is horizontal (for a correct scroll handling)                                                               |\n| `swipeThreshold`                 | `number`             | `100`                            | Swiping threshold that when reached calls `onSwipeComplete`                                                                                |\n| `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']` |\n| `useNativeDriver`                | `bool`               | `false`                          | Defines if animations should use native driver                                                                                             |\n| `useNativeDriverForBackdrop`     | `bool`               | `null`                           | Defines if animations for backdrop should use native driver (to avoid flashing on android)                                                 |\n| `hideModalContentWhileAnimating` | `bool`               | `false`                          | Enhances the performance by hiding the modal content until the animations complete                                                         |\n| `propagateSwipe`                 | `bool` or `func`     | `false`                          | Allows swipe events to propagate to children components (eg a ScrollView inside a modal)                                                   |\n| `style`                          | `any`                | `null`                           | Style applied to the modal                                                                                                                 |\n\n## Frequently Asked Questions\n\n### The component is not working as expected\n\nUnder the hood `react-native-modal` uses react-native original [Modal component](https://reactnative.dev/docs/modal).  \nBefore 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).\n\n### The backdrop is not completely filled/covered on some Android devices (Galaxy, for one)\n\nReact-Native has a few issues detecting the correct device width/height of some devices.  \nIf you're experiencing this issue, you'll need to install [`react-native-extra-dimensions-android`](https://github.com/Sunhat/react-native-extra-dimensions-android).  \nThen, provide the real window height (obtained from `react-native-extra-dimensions-android`) to the modal:\n\n```javascript\nconst deviceWidth = Dimensions.get('window').width;\nconst deviceHeight =\n  Platform.OS === 'ios'\n    ? Dimensions.get('window').height\n    : require('react-native-extra-dimensions-android').get(\n        'REAL_WINDOW_HEIGHT',\n      );\n\nfunction WrapperComponent() {\n  const [isModalVisible, setModalVisible] = useState(true);\n\n  return (\n    \u003cModal\n      isVisible={isModalVisible}\n      deviceWidth={deviceWidth}\n      deviceHeight={deviceHeight}\u003e\n      \u003cView style={{flex: 1}}\u003e\n        \u003cText\u003eI am the modal content!\u003c/Text\u003e\n      \u003c/View\u003e\n    \u003c/Modal\u003e\n  );\n}\n```\n\n### How can I hide the modal by pressing outside of its content?\n\nThe prop `onBackdropPress` allows you to handle this situation:\n\n```javascript\n\u003cModal\n  isVisible={isModalVisible}\n  onBackdropPress={() =\u003e setModalVisible(false)}\u003e\n  \u003cView style={{flex: 1}}\u003e\n    \u003cText\u003eI am the modal content!\u003c/Text\u003e\n  \u003c/View\u003e\n\u003c/Modal\u003e\n```\n\n### How can I hide the modal by swiping it?\n\nThe prop `onSwipeComplete` allows you to handle this situation (remember to set `swipeDirection` too!):\n\n```javascript\n\u003cModal\n  isVisible={isModalVisible}\n  onSwipeComplete={() =\u003e setModalVisible(false)}\n  swipeDirection=\"left\"\u003e\n  \u003cView style={{flex: 1}}\u003e\n    \u003cText\u003eI am the modal content!\u003c/Text\u003e\n  \u003c/View\u003e\n\u003c/Modal\u003e\n```\n\nNote that when using `useNativeDriver={true}` the modal won't drag correctly. This is a [known issue](https://github.com/react-native-community/react-native-modal/issues/163#issuecomment-409760695).\n\n### The modal flashes in a weird way when animating\n\nUnfortunately this is a [known issue](https://github.com/react-native-community/react-native-modal/issues/92) that happens when `useNativeDriver=true` and must still be solved.  \nIn the meanwhile as a workaround you can set the `hideModalContentWhileAnimating` prop to `true`: this seems to solve the issue.\nAlso, do not assign a `backgroundColor` property directly to the Modal. Prefer to set it on the child container.\n\n### The modal background doesn't animate properly\n\nAre you sure you named the `isVisible` prop correctly? Make sure it is spelled correctly: `isVisible`, not `visible`.\n\n### The modal doesn't change orientation\n\nAdd a `supportedOrientations={['portrait', 'landscape']}` prop to the component, as described [in the React Native documentation](https://reactnative.dev/docs/modal.html#supportedorientations).\n\nAlso, if you're providing the `deviceHeight` and `deviceWidth` props you'll have to manually update them when the layout changes.\n\n### I can't show multiple modals one after another\n\nUnfortunately right now react-native doesn't allow multiple modals to be displayed at the same time.\nThis means that, in `react-native-modal`, if you want to immediately show a new modal after closing one you must first make sure that the modal that your closing has completed its hiding animation by using the `onModalHide` prop.\n\n### I can't show multiple modals at the same time\n\nSee the question above.\nShowing multiple modals (or even alerts/dialogs) at the same time is not doable because of a react-native bug.\nThat said, I would strongly advice against using multiple modals at the same time because, most often than not, this leads to a bad UX, especially on mobile (just my opinion).\n\n### The StatusBar style changes when the modal shows up\n\nThis issue has been discussed [here](https://github.com/react-native-community/react-native-modal/issues/50).  \nThe TLDR is: it's a know React-Native issue with the Modal component 😞\n\n### The modal is not covering the entire screen\n\nThe modal style applied by default has a small margin.  \nIf you want the modal to cover the entire screen you can easily override it this way:\n\n```js\n\u003cModal style={{margin: 0}}\u003e...\u003c/Modal\u003e\n```\n\n### I can't scroll my ScrollView inside of the modal\n\nEnable propagateSwipe to allow your child components to receive swipe events:\n\n```js\n\u003cModal propagateSwipe\u003e...\u003c/Modal\u003e\n```\n\nPlease notice that this is still a WIP fix and might not fix your issue yet, see [issue #236](https://github.com/react-native-community/react-native-modal/issues/236).\n\n### The modal enter/exit animation flickers\n\nMake sure your `animationIn` and `animationOut` are set correctly.  \nWe noticed that, for example, using `fadeIn` as an exit animation makes the modal flicker (it should be `fadeOut`!).\nAlso, some users have noticed that setting backdropTransitionOutTiming={0} can fix the flicker without affecting the animation.\n\n### The custom backdrop doesn't fill the entire screen\n\nYou need to specify the size of your custom backdrop component. You can also make it expand to fill the entire screen by adding a `flex: 1` to its style:\n\n```javascript\n\u003cModal isVisible={isModalVisible} customBackdrop={\u003cView style={{flex: 1}} /\u003e}\u003e\n  \u003cView style={{flex: 1}}\u003e\n    \u003cText\u003eI am the modal content!\u003c/Text\u003e\n  \u003c/View\u003e\n\u003c/Modal\u003e\n```\n\n### The custom backdrop doesn't dismiss the modal on press\n\nYou can provide an event handler to the custom backdrop element to dismiss the modal. The prop `onBackdropPress` is not supported for a custom backdrop.\n\n```javascript\n\u003cModal\n  isVisible={isModalVisible}\n  customBackdrop={\n    \u003cTouchableWithoutFeedback onPress={dismissModalHandler}\u003e\n      \u003cView style={{flex: 1}} /\u003e\n    \u003c/TouchableWithoutFeedback\u003e\n  }\n/\u003e\n```\n\n## Available animations\n\nTake 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).\n\n## Alternatives\n\n- [React Native's built-in `\u003cModal\u003e` component](https://reactnative.dev/docs/modal.html)\n- [React Native Paper `\u003cModal\u003e` component](https://callstack.github.io/react-native-paper/modal.html)\n- [React Native Modalfy](https://github.com/colorfy-software/react-native-modalfy)\n\n## Acknowledgements\n\nThanks [@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!\n\nPull requests, feedbacks and suggestions are welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-native-modal%2Freact-native-modal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-native-modal%2Freact-native-modal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-native-modal%2Freact-native-modal/lists"}