usePortal
🌀 React hook for using Portals
Need to make dropdowns, lightboxes/modals/dialogs, global message notifications, or tooltips in React? React Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component (react docs).
Examples
Installation
yarn add react react-dom react-useportal
Usage
Stateless
import usePortal from 'react-useportal' <Portal> This text is portaled at the end of documentbody!</Portal> <Portal => This text is portaled into San Francisco!</Portal>
With State
import usePortal from 'react-useportal' const App = var openPortal closePortal isOpen Portal = // want to use array destructuring? You can do that too var openPortal closePortal isOpen Portal = return <> <button => Open Portal </button> isOpen && <Portal> <p> This Portal handles its own state' ' <button =>Close me!</button> hit ESC or click outside of me </p> </Portal> </>
Need Animations?
import usePortal from 'react-useportal' const App = const openPortal closePortal isOpen Portal = return <> <button => Open Portal </button> <Portal> <p => This Portal handles its own state' ' <button =>Close me!</button> hit ESC or click outside of me </p> </Portal> </>
Make sure you are passing the html synthetic event to the openPortal
. i.e. onClick={e => openPortal(e)}
Options
Option | Description |
---|---|
closeOnOutsideClick |
This will close the portal when not clicking within the portal. Default is true |
closeOnEsc |
This will allow you to hit ESC and it will close the modal. Default is true |
renderBelowClickedElement |
This will put the portal right under the element that you click on. Great for dropdowns. Required to pass event to openPortal onClick={event => openPortal(event)} |
bindTo |
This is the DOM node you want to attach the portal to. By default it attaches to document.body |
isOpen |
This will be the default for the portal. Default is false |
Option Usage
const openPortal closePortal togglePortal isOpen Portal } =
Todos
- add support for popup windows resource 1 resource 2. Maybe something like
const openPortal closePortal isOpen Portal = // window.open('', '', 'width=600,height=400,left=200,top=200')
- make isomorphic
- make work without requiring the html synthetic event & document when you are required to have it and when you are not
- clean up code
- make work with both
[openPortal, closePortal, ..., Portal] = usePortal()
and like current object destructuring