A magic modal that can be used imperatively from anywhere! 🦄
npm install react-native-magic-modal

> [!NOTE]
> Simplify your modal management in React Native with the React Native Magic Modal library. Effortlessly control modals, streamline complex flows, and create a seamless user experience.
> [!TIP]
> Our new version just got released with full support for multiple modals! See the breaking changes.
- 📲 Easy Integration: Seamlessly integrate with your React Native app.
- 🔄 Complex Flow Management: Manage intricate modal sequences effortlessly.
- 🔧 Customizable: Tailor modals to fit your app's unique requirements.
React Native Magic Modal offers a superior experience compared to traditional modal implementations:
- 🎨 Stylish and Responsive: Designed to look great on both iOS and Android.
- 🚀 Developer Friendly: Simple to use, with a focus on developer experience.
- 🧩 Versatile: Adaptable to a wide range of modal scenarios.
- Installation
- Quickstart
- Examples
- Documentation
- FAQ
- Contributors
Add peer dependencies to your project, if you haven't already:
``bash`
yarn add react-native-reanimated
yarn add react-native-gesture-handler
Install the package:
`bash`
yarn add react-native-magic-modal
Insert a MagicModalPortal at the top of your application structure, and a GestureHandlerRootView if you haven't already:
`javascript
import { MagicModalPortal } from "react-native-magic-modal";
import { GestureHandlerRootView } from "react-native-gesture-handler";
export default function App() {
return (
);
}
`
Tip: the root _layout.tsx is usually the best place to put it in a project using expo-router.
Showcasing modal management on iOS and Android platforms:
| iOS | Android |
| ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| |
|
Here's the preferred usage pattern for the library:
`js
import React from "react";
import { View, Text, TouchableOpacity } from "react-native";
import {
MagicModalPortal,
magicModal,
useMagicModal,
MagicModalHideReason
} from "react-native-magic-modal";
import { GestureHandlerRootView } from "react-native-gesture-handler";
type ConfirmationModalReturn = {
success: boolean;
};
const ConfirmationModal = () => {
const { hide } = useMagicModal
return (
);
};
const ResponseModal = ({ text }) => {
const { hide } = useMagicModal();
return (
);
};
const handleConfirmationFlow = async () => {
// You can call show with or without props, depending on the requirements of the modal.
const result = await magicModal.show
// Hide could potentially be a backdrop press, a back button press, or a swipe gesture.
if (result.reason !== MagicModalHideReason.INTENTIONAL_HIDE) {
// User cancelled the flow
return;
}
if (result.data.success) {
return magicModal.show(() =>
}
return magicModal.show(() =>
};
export const MainScreen = () => {
return (
);
};
`
You can also hide modals imperatively outside of the modal context. For that, we provide the global hide method, that requires a modal id:
`js
import { magicModal } from "react-native-magic-modal";
const QuickModal = ({ text }) => {
return (
);
};
const handleQuickModal = async () => {
const { modalId } = magicModal.show(QuickModal);
// Wait for 2 seconds before closing the modal
await new Promise((resolve) => setTimeout(resolve, 2000));
// Note that it's usually preferrable to use the hide method from the modal context
// You can even put it inside useEffects to handle auto-dismissal for you.
magicModal.hide({ modalId });
};
export const MainScreen = () => {
return (
);
};
`
Refer to the kitchen-sink example for detailed usage scenarios.
Access the complete documentation here.
Q: Can I have two modals showing up at the same time?
A: Yes. With v4+, you can now have multiple modals showing up at the same time.
---
Q: Can I use Scrollables inside the modal?
A:
Yes, but Scrollables can't be used with swipe gestures enabled, as they conflict. Pass in swipeDirection: undefined on the magicModal.show function to disable gestures on them.
If your use-case is a scrollable bottom-sheet, I recommend going with Gorhom's react-native-bottom-sheet for this use-case temporarily.
---
Q: Modals are appearing on top of native modal screens, such as the image picker. How can I fix this?
A:
This behavior can be disabled by calling magicModal.disableFullWindowOverlay() before showing the modal. This will prevent the modal from appearing on top of native modal screens.
You can also call magicModal.enableFullWindowOverlay()` to re-enable it.
Special thanks to everyone who contributed to making React Native Magic Modal a robust and user-friendly library. See the full list.
See the contributing guide to learn how to contribute to the repository.
React Native Magic Modal is licensed under the MIT License.