0

Is there a view/component/anything that can be used in one place in a react native app that would be placed above all the content - I need it for toast component. I tried using Portals, Root Siblings, Modals etc. but nothing goes above the screen that has presentation: "modal" on iOS.

I specifically want to keep presentation: "modal" for some screens and I need toast messages to be available there. I know I could render couple of instances of toast component including those screens with presentation: "modal", but I am looking for something global - that would be above all the content no matter what.

I know it is possible because I've seen apps like WhatsApp have it (the toast message is literally floating above everything because no matter where you go it persists there, even if you go on screens with presentation: "modal). Of course they use native views like UIWindow with windowLevel (.alert or above) but I was wondering does anything like that exist in react native/expo ecosystem?

If not, how come has no one come to an idea to create an expo module for example that exposes that overlaying view - it would be useful for toasts, modals, sheets, portals etc... (I was thinking about trying to do that myself, but Im not sure how doable that would be for me considering my skill level and the amount of free time)

2
  • Create view and add style={{position:'absolute', width:200, height:50, backgroundColor:'red'}} and place that view in modal, and check. Commented Sep 3 at 6:35
  • Its not above the screen with presentation: 'modal' and even if it was I still wouldn't be able to click "through" modal - so the behavior differs a lot from what I am looking for. It would be above it if I placed that modal inside the mentioned view even tho thats still not wanted behavior. I am looking for a view that can be on top of everything globally. If you mock a toast on whatsapp (for example delete one message) and try navigating to the settings->notifications->sound (where sound screen has presentation modal) you will see that toast stays on top regardless of where I navigate. Commented Sep 3 at 12:08

1 Answer 1

1

I found an answer and Im gonna put it and leave it here in case it helps someone else as well...

The component is FullWindowOverlay from 'react-native-screens' (https://github.com/software-mansion/react-native-screens?tab=readme-ov-file#fullwindowoverlay)

And this is the usage that solved my problem:

In entry point of the app (e.g. _layout.tsx) you need to import enableScreens function from 'react-native-screens' and put it at the start of the file as shown below:

import Toaster from "components/shared/toaster/Toaster";
import { AppStateProvider } from "contexts/shared/app-state";
import { ThemeProvider } from "contexts/shared/theme";
import { TranslationsProvider } from "contexts/shared/translations";
import { Stack } from "expo-router";
import useDefaultScreenOptions from "hooks/default-screen-options";
import { KeyboardProvider } from "react-native-keyboard-controller";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { enableScreens } from "react-native-screens";

enableScreens();

export default function RootLayout() {
  return (
    <SafeAreaProvider>
      <AppStateProvider>
        <TranslationsProvider>
          <ThemeProvider>
            <KeyboardProvider>
              <Layout />
              <Toaster />
            </KeyboardProvider>
          </ThemeProvider>
        </TranslationsProvider>
      </AppStateProvider>
    </SafeAreaProvider>
  );
}

function Layout() {
  const defaultScreenOptions = useDefaultScreenOptions("stack");

  return (
    <Stack
      screenOptions={{
        headerShown: false,
        ...defaultScreenOptions,
      }}
    />
  );
}

Then wrap your toast with "FullWindowOverlay" as shown below:

import { FullWindowOverlay } from "react-native-screens";

export default function Toaster() {
  return (
    <FullWindowOverlay>
      <YourToastComponent />
    </FullWindowOverlay>
  );
}

As stated in react-native-screens docs you should treat FullWindowOverlay as a wrapper, providing full-screen, transparent view which receives no props and should ideally render one child View, being the root of its view hierarchy.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.