react-native-multiple-modals

repository·main·Indexed 41 days ago

https://github.com/paufau/react-native-multiple-modals

A native layering library for React Native version 3.5.0 that enables displaying multiple modals, sheets, and overlays simultaneously. It provides native performance and accessibility (WCAG) support, allowing overlays to appear above default native Modals and bottom tab navigation. Key features include the ModalView component, focus trapping via useFocusTrap, and stack management with useModalStack.

Tokens
11.7K
Snippets
32
Records
45
Agent score
51%

What's inside react-native-multiple-modals

  1. Introduction to React Native Multiple Modals

    main
    React Native Multiple Modals provides native layering for modals, sheets, and overlays in React Native applications. It is designed to solve the limitation of standard React Native modals by allowing multiple instances to be displayed simultaneously and ensuring they appear on top of other native elements, such as the default Modal component and bottom tab navigation.
  2. Key features of React Native Multiple Modals

    main

    The library provides several advanced layering and UX capabilities:

    • Multiple Instances: Shows multiple modals/sheets at the same time.
    • Native Layering: Displays on top of the default React Native Modal and above bottom tab navigation.
    • Gesture Support: Supports gesture handlers out of the box.
    • Responsive Layout: Automatically adjusts content when the device is rotated.
    • Status Bar: Provides enhanced status bar configuration.
    • Accessibility: Built with WCAG accessibility support in mind.
  3. Understand ModalView stacking order

    main

    The stacking order of ModalView instances is determined by the order in which they were opened, rather than their order in the JSX markup.

    • When a ModalView mounts, it is placed on top of all currently open modals.
    • The topmost modal is the only one that receives interaction for the Android back button or the Escape key on Web.
    • Tapping a backdrop only triggers the onRequestDismiss callback of the topmost modal.
  4. How ModalView compares to other modal solutions

    main

    Compared to standard React Native or JS-based modal libraries, react-native-multiple-modals (via ModalView) provides a native implementation that allows for stacking multiple modals simultaneously.

    Key technical differences:

    • Implementation: Uses native primitives (UIWindow on iOS, Dialog on Android, and portals on Web) rather than JS-based portals.
    • Stacking: Unlike the standard React Native Modal (which cannot stack on iOS) or react-native-modal, ModalView allows any number of modals to stack over each other and over a built-in Modal.
    • Accessibility: Provides full accessibility support, unlike JS-based solutions like react-native-modalfy or portal libraries.
    | | Native or JS | Multiple at once | Accessibility |
    | --- | --- | --- | --- |
    | **react-native-multiple-modals** | Native | ✅ | ✅ |
    | [`Modal`](https://reactnative.dev/docs/modal) (React Native) | Native | ❌ on iOS | ✅ |
    | [react-native-modal](https://github.com/react-native-modal/react-native-modal) | Native | ❌ | ✅ |
    | [react-native-modalfy](https://github.com/colorfy-software/react-native-modalfy) | JS | ✅ | ❌ |
    | [@react-navigation/native-stack](https://reactnavigation.org/docs/native-stack-navigator/) | Native | ✅ | ❌ |
    | [@gorhom/portal](https://github.com/gorhom/react-native-portal), [react-native-portalize](https://github.com/jeremybarbet/react-native-portalize) | JS | ✅ | ❌ |
  5. Compare react-native-multiple-modals with other modal solutions

    main

    Use react-native-multiple-modals when you need a native implementation that supports showing multiple modals at once and provides full accessibility (WCAG) support.

    Unlike the standard React Native Modal, this library allows multiple instances on iOS. Unlike JS-based solutions like react-native-modalfy or @gorhom/portal, it uses native layering, which is better for performance and integration with native components like bottom tabs.

  6. Use the ModalView component

    main

    The ModalView component is displayed when it is mounted in the React tree and hidden when it is removed. To handle user interactions like tapping the backdrop or pressing the hardware back button, provide an onRequestDismiss callback to update your local visibility state.

    import { ModalView } from "react-native-multiple-modals";
    
    const YourComponent = () => {
      const [isVisible, setVisibility] = useState(false);
    
      return (
        <View>
          <Button text="Open modal" onPress={() => setVisibility(true)} />
          {isVisible && (
            <ModalView
              animationType="fade"
              onRequestDismiss={() => setVisibility(false)}
            >
              <YourContentView />
            </ModalView>
          )}
        </View>
      );
    };
  7. Blur the backdrop using expo-blur

    main

    To replace the default translucent backdrop of a ModalView with a blur effect, use the renderBackdrop prop.

    Pass a function to renderBackdrop that returns a component (such as BlurView from expo-blur). The returned element is rendered inside a pressable that handles backdrop taps, so it should use style={{ flex: 1 }} to fill the available space.

    Note that tapping the blurred area will trigger onRequestDismiss by default because the pressable wraps the returned element.

    import { BlurView } from 'expo-blur';
    import { ModalView } from 'react-native-multiple-modals';
    
    const BlurredModal = ({ onClose, children }) => (
      <ModalView
        contentContainerStyle={{ justifyContent: 'center', alignItems: 'center' }}
        onRequestDismiss={onClose}
        renderBackdrop={() => <BlurView intensity={40} style={{ flex: 1 }} />}
      >
        {children}
      </ModalView>
    );
  8. Run the react-native-multiple-modals example app

    main

    The example is an Expo app that demonstrates react-native-multiple-modals on iOS, Android, and web.

    Important: Because the library uses custom native (Fabric) code, you cannot use Expo Go. You must run the app as a dev build using npx expo run:ios or npx expo run:android after performing a prebuild.

    cd example
    npm install                 # links the library via file:.. and installs deps
    npx expo prebuild --clean   # generates ios/ + android/ (regenerable; gitignored)
    
    npx expo run:ios            # iOS simulator
    npx expo run:android        # Android emulator/device
    npx expo start --web        # web (react-native-web)