GeekyAnts / react-native-aria

A library of React Hooks for React-Native (Android/iOS/web) to provide accessible UI primitives for a design system.
https://react-native-aria.geekyants.com
MIT License
226 stars 12 forks source link

Portals/Overlays: Portal Render Target #30

Open tegan-rbi opened 2 years ago

tegan-rbi commented 2 years ago

Hello!

It would be useful to provide a component that allows consumers of the library to choose where Portals are rendered instead of as a sibling to the children prop of the PortalProvider. It is useful because the way "portals" are being implemented here changes where the component being portalled renders in the React tree. This has implications for Context. Below if we try to render a NativeBaseModal (which uses PortalProvider), ContextProviderA and ContextProviderB are not accessible from within the Modal component since it is ultimately rendered directly under the NativeBaseProvider.

  <NativeBaseProvider> // NativeBaseProvider provides theme context and PortalProvider is consumed by NativeBase
    <ContextProviderA>
      <ContextProviderB>
        <App />
      <ContextProviderB>
    <ContextProviderA>
    // Portals created by ContextProviderA, ContextProviderB, and App are all rendered here! Outside of the context providers!
  </NativeBaseProvider>

I have already created a patch for my own project to add this and can put up a PR if it would be desirable.

Ultimately I just created a PortalRenderer component below:

export function PortalRenderer() {
  const context = usePortalProvider()!;

  return context.items?.map(
    (item) => <React.Fragment key={item.id}>{item.node}</React.Fragment>
  ) ?? null;
}

I also deleted: https://github.com/GeekyAnts/react-native-aria/blob/ec14df07ea1273f81e73eeb4ac41f63d455495b1/packages/overlays/src/Portal.tsx#L59-L62.

This is obviously a breaking change since Portals are no longer automatically rendered and would require users to consume the PortalRenderer component somewhere in order to actually render their portals.

MelkorNemesis commented 2 years ago

+1 I'm currently facing the same issue. Because of this, I'm not able to access my application's contexts.