Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
@gorhom/portal
Advanced tools
@gorhom/portal is a React Native package that allows you to create and manage portals. Portals provide a way to render children into a DOM node that exists outside the DOM hierarchy of the parent component. This is particularly useful for rendering modals, tooltips, and other UI elements that need to appear above other content.
Creating a Portal
This code demonstrates how to create a simple portal using @gorhom/portal. The portal renders a modal-like view that appears above the main content when a button is pressed.
import { PortalProvider, Portal } from '@gorhom/portal';
import React from 'react';
import { View, Text, Button } from 'react-native';
const App = () => {
const [visible, setVisible] = React.useState(false);
return (
<PortalProvider>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Show Portal" onPress={() => setVisible(true)} />
{visible && (
<Portal>
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'white' }}>This is a portal!</Text>
<Button title="Close" onPress={() => setVisible(false)} />
</View>
</Portal>
)}
</View>
</PortalProvider>
);
};
export default App;
Nested Portals
This code demonstrates how to create nested portals using @gorhom/portal. The nested portal appears above the first portal when a button is pressed.
import { PortalProvider, Portal } from '@gorhom/portal';
import React from 'react';
import { View, Text, Button } from 'react-native';
const App = () => {
const [visible, setVisible] = React.useState(false);
const [nestedVisible, setNestedVisible] = React.useState(false);
return (
<PortalProvider>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button title="Show Portal" onPress={() => setVisible(true)} />
{visible && (
<Portal>
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.5)', justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'white' }}>This is a portal!</Text>
<Button title="Show Nested Portal" onPress={() => setNestedVisible(true)} />
{nestedVisible && (
<Portal>
<View style={{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, backgroundColor: 'rgba(0,0,0,0.7)', justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ color: 'white' }}>This is a nested portal!</Text>
<Button title="Close Nested" onPress={() => setNestedVisible(false)} />
</View>
</Portal>
)}
<Button title="Close" onPress={() => setVisible(false)} />
</View>
</Portal>
)}
</View>
</PortalProvider>
);
};
export default App;
react-native-modal is a widely-used package for creating modals in React Native. It provides a lot of customization options and animations. Unlike @gorhom/portal, it is specifically designed for modals and does not support other types of portals.
react-native-paper is a UI library that includes a Portal component among many other UI components. It is a more comprehensive solution for building React Native applications with Material Design. The Portal component in react-native-paper is similar to @gorhom/portal but is part of a larger UI toolkit.
react-native-root-siblings is another package that allows you to render elements outside the main React Native view hierarchy. It is similar to @gorhom/portal in that it can be used to create modals, toasts, and other overlay components. However, it is less focused on portals specifically and more on general overlay management.
A simplified portal implementation for ⭕️ React Native ⭕️.
React Native Web
.Expo
, check out the project Expo Snack.TypeScript
.yarn add @gorhom/portal
This is the very simple usage of this library, where you will teleport your content to the PortalProvider
layer of the app.
First, you will need to add PortalProvider
to your root component - this usually be the App.tsx
.
export const App = () => (
<PortalProvider>
{... your app goes here}
</PortalProvider>
);
Last, you wrap the content that you want to teleport with Portal
.
const BasicScreen = () => {
return (
{ ... }
<Portal>
<Text>
Text to be teleported to the root host
</Text>
</Portal>
{ ... }
);
};
This is when you need to teleport your content to a custom portal host PortalHost
at any layer in the app.
First, you will need to add PortalProvider
to your root component - this usually be the App.tsx
.
export const App = () => (
<PortalProvider>
{... your app goes here ...}
</PortalProvider>
);
Second, you will need to add PortalHost
at any layer in your app, with a custom name.
const CustomView = () => {
return (
{ ... }
<PortalHost name="CustomPortalHost" />
{ ... }
);
};
Last, you wrap the content that you want to teleport with Portal
and the custom portal host name.
const BasicScreen = () => {
return (
{ ... }
<Portal hostName="CustomPortalHost">
<Text>
Text to be teleported to the CustomView component
</Text>
</Portal>
{ ... }
);
};
In order to get your teleported content on top of all native views, you will need to wrap your content with FullWindowOverlay
from react-native-screens
.
import { FullWindowOverlay } from 'react-native-screens';
const BasicScreen = () => {
return (
{ ... }
<Portal>
<FullWindowOverlay style={StyleSheet.absoluteFill}>
<Text>
Text to be teleported to the CustomView component
</Text>
</FullWindowOverlay>
</Portal>
{ ... }
);
};
To avoid issues when using the React Native Portal with React Native Gesture Handler, you must place the PortalProvider
under the GestureHandlerRootView
, otherwise it might freeze your app.
export const App = () => (
<GestureHandlerRootView>
<PortalProvider>
{... your app goes here}
</PortalProvider>
</GestureHandlerRootView>
);
Read more about the app freezing issue.
name
Portal's key or name to be used as an identifer.
required:
NO |type:
string |default:
auto generated unique key
hostName
Host's key or name to teleport the portal content to.
required:
NO |type:
string |default:
'root'
handleOnMount
Override internal mounting functionality, this is useful if you want to trigger any action before mounting the portal content.
type handleOnMount = (mount?: () => void) => void;
required:
NO |type:
function |default:
undefined
handleOnUnmount
Override internal un-mounting functionality, this is useful if you want to trigger any action before un-mounting the portal content.
type handleOnUnmount = (unmount?: () => void) => void;
required:
NO |type:
function |default:
undefined
children
Portal's content.
required:
NO |type:
ReactNode | ReactNode[] |default:
undefined
name
Host's key or name to be used as an identifier.
required:
YES |type:
string
usePortal
To access internal functionalities of all portals.
/**
* @param hostName host name or key.
*/
type usePortal = (hostName: string = 'root') => {
/**
* Register a new host.
*/
registerHost: () => void;
/**
* Deregister a host.
*/
deregisterHost: () => void;
/**
* Add portal to the host container.
* @param name portal name or key
* @param node portal content
*/
addPortal: (name: string, node: ReactNode) => void;
/**
* Update portal content.
* @param name portal name or key
* @param node portal content
*/
updatePortal: (name: string, node: ReactNode) => void;
/**
* Remove portal from host container.
* @param name portal name or key
*/
removePortal: (name: string) => void;
};
To keep this library maintained and up-to-date please consider sponsoring it on GitHub. Or if you are looking for a private support or help in customizing the experience, then reach out to me on Twitter @gorhom.
FAQs
A simplified portal implementation for ⭕️ React Native ⭕️
The npm package @gorhom/portal receives a total of 155,929 weekly downloads. As such, @gorhom/portal popularity was classified as popular.
We found that @gorhom/portal demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.