UNPKG

react-portal-hook

Version:
156 lines (121 loc) 3.08 kB
# react-portal-hook A small React portal library made with hooks. Allows you to render an indefinite number of portals without having to define them in advance. Useful for event-driven notifications or modals where you don't know how many items will be rendered at a given time. ## Getting Started ### Installation To use react-portal-hook in your project, run: ```shell script npm install react-portal-hook ``` ### Setup Wrap your root component with `PortalProvider`. ```jsx // app.jsx import { PortalProvider } from "react-portal-hook"; const App = () => { return ( <PortalProvider> <RootComponent /> </PortalProvider> ); }; ``` ### Usage **Example** - Modals: By default, portals will be appended to `document.body`. [Demo](https://codesandbox.io/s/react-portal-hook-modal-example-iow95) ```jsx // page.jsx import { usePortals } from "react-portal-hook"; const Modal = ({ closeModal }) => { return ( <div> <h2>Title</h2> <p>This is a modal</p> <button onClick={closeModal}>Close Modal</button> </div> ); }; export const Page = () => { const portalManager = usePortals(); const openModal = () => { portalManager.open(portal => <Modal closeModal={portal.close} />); }; return ( <div> <h2>Title</h2> <p>This is a page</p> <button onClick={openModal}>Open Modal</button> </div> ); }; ``` **Example** - Notifications: You can specify a DOM node in which to render portals with the `appendTo` option: [Demo](https://codesandbox.io/s/react-portal-hook-notifications-example-os1b4) ```jsx // layout.jsx import { useRef } from "react"; import { usePortals } from "react-portal-hook"; const Notification = ({ closeNotification }) => { return ( <div> <p> This is a notification{" "} <button onClick={closeNotification}>Close Notification</button> </p> </div> ); }; export const Layout = () => { const portalManager = usePortals(); const notificationEl = useRef(); const showNotification = () => { // Calling this from anywhere in your app will render a notification portalManager.open( portal => <Notification closeNotification={portal.close} />, { appendTo: notificationEl.current } ); }; return ( <div> <div id="notification-holder" ref={notificationEl} /> <button onClick={showNotification}>Show Notification</button> </div> ); }; ``` ## API Documentation #### `portalManager` ```typescript interface PortalManager { /** * The react element you want to render in the portal */ element: ((portal: Portal) => React.ReactElement) | React.ReactElement; options?: { /** * An ID to avoid duplicate portals */ id?: string; /** * A DOM node in which to render the portal */ appendTo?: Element; /** * A callback that is fired when the portal closes */ onClose?: () => void; }; } ``` #### `Portal` ```typescript interface Portal { /** * A function to close the Portal */ close: () => void; } ```