Skip to main content

Portal

Utilities

Portal

Context-aware portal built on @gorhom/portal with bridge support.

Usage

Render components outside the DOM/native hierarchy without losing context.

Highlights

  • registerPortalContext helper
  • Used by Modal, Popover, Select

When to use it

  • Any overlay must escape clipping containers.
  • Share React contexts with Portal children automatically.

Examples

Default

Preview (Web)
import { StyleSheet, View } from 'react-native';
import { Portal, PortalProvider } from 'react-native-molecules/components/Portal';
import { Text } from 'react-native-molecules/components/Text';

const styles = StyleSheet.create({
  container: {
      padding: 16,
      borderWidth: 1,
      borderColor: '#10b981',
      borderRadius: 12,
      gap: 12,
  },
});

export default function Example() {
  return (
      <View style={{ gap: 10 }}>
          <PortalProvider>
              <View style={styles.container}>
                  <Text>This child is placed in the parent view.</Text>

                  <Portal>
                      <Text>This child is rendered outside of the root parent.</Text>
                  </Portal>
              </View>
          </PortalProvider>
      </View>
  );
}

With Context Bridge

Preview (Web)
import { createContext, useContext } from 'react';
import { StyleSheet, View } from 'react-native';
import { Portal, registerPortalContext } from 'react-native-molecules/components/Portal';
import { Text } from 'react-native-molecules/components/Text';

const NumberContext = createContext(10);
const StringContext = createContext('hello world');

registerPortalContext(NumberContext);

const styles = StyleSheet.create({
  container: {
      padding: 16,
      borderWidth: 1,
      borderColor: '#10b981',
      borderRadius: 12,
      gap: 8,
  },
});

function ChildComponent({ text }: { text: string }) {
  const number = useContext(NumberContext);
  const string = useContext(StringContext);

  return (
      <>
          <Text>number (bridged): {number}</Text>
          <Text>string (not bridged): {string}</Text>
          <Text>{text}</Text>
      </>
  );
}

export default function Example() {
  return (
      <NumberContext.Provider value={42}>
          <StringContext.Provider value="Aloha">
              <View style={styles.container}>
                  <ChildComponent text="This child is placed in the parent view." />

                  <Portal>
                      <ChildComponent text="This child is rendered outside of the root parent." />
                  </Portal>
              </View>
          </StringContext.Provider>
      </NumberContext.Provider>
  );
}