New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-cool-portal

Package Overview
Dependencies
Maintainers
1
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-cool-portal

React hook for Portals, which renders modals, dropdowns, tooltips etc. to or else.

  • 0.1.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
5K
decreased by-20.82%
Maintainers
1
Weekly downloads
 
Created
Source

⚠️ This library is in-progress, API might changed rapidly. I don't recommend to use it now. If you'd like to give it a try, please follow the release note for any change. Here's the milestone.

React Cool Portal

This is a React hook for Portals. It helps you render an element outside of its component hierarchy. From now on you will never need to struggle with modals, dropdowns, tooltips etc. Hope you guys 👍🏻 it.

❤️ it? ⭐️ it on GitHub or Tweet about it.

build status coverage status npm version npm downloads npm downloads npm bundle size MIT licensed All Contributors PRs welcome Twitter URL

Live Demo

portal_modal

⚡️ Try yourself: https://react-cool-portal.netlify.com

Milestone

  • Auto creating/removing the container of the portal
  • Renders element to the portal container
  • Show/hide/toggle the portal
  • onShow/onHide event callbacks
  • Support clickOutsideToHide and escToHide interactions
  • Provide a flexible way to handle animations
  • Server-side rendering compatibility
  • Unit testing
  • Demo app
  • Demo code
  • Typescript type definition
  • CI/CD
  • Documentation

Requirement

To use react-cool-portal, you must use react@16.8.0 or greater which includes hooks.

Installation

This package is distributed via npm.

$ yarn add react-cool-portal
# or
$ npm install --save react-cool-portal

Usage

Here are some minimal examples of how does it work. You can learn more about it by checking the API out.

Basic Use Case

Inserts an element or component into the a different location in the DOM.

import React from 'react';
import usePortal from 'react-cool-portal';

const App = () => {
  const { Portal } = usePortal();

  return (
    <div>
      <Portal>
        <div>
          Wow! I am rendered outside the DOM hierarchy of my parent component.
        </div>
      </Portal>
    </div>
  );
};

By default, the children of portal is rendered into <div id="react-cool-portal"> of <body>. You can use your own container by the containerId option.

import React from 'react';
import usePortal from 'react-cool-portal';

const App = () => {
  const { Portal } = usePortal({ containerId: 'my-portal-root' });

  return (
    <div>
      <Portal>
        <div>Now I am rendered into the "my-portal-root" element.</div>
      </Portal>
    </div>
  );
};

Note: If the container element doesn't exist, we will create it for you.

Use with State

react-cool-portal provides many useful features, which enable you to build a component with state like modal, dropdown, tooltip and so on.

import React from 'react';
import usePortal from 'react-cool-portal';

const App = () => {
  const { Portal, isShow, show, hide, toggle } = usePortal({
    defaultShow: false, // The default visibility of portal, default is true
    onShow: e => {
      // Triggered when portal is shown
      // The event object will be the parameter of "show()"
    },
    onHide: e => {
      // Triggered when portal is hidden
      // The event object will be the parameter of "hide()", MouseEvent (on clicks outside) or KeyboardEvent (press ESC key)
    }
  });

  return (
    <div>
      <button onClick={show}>Open Modal</button>
      <button onClick={hide}>Close Modal</button>
      <button onClick={toggle}>{isShow ? 'Close' : 'Open'} Modal</button>
      <Portal>
        <div class="modal" tabIndex={-1}>
          <div
            class="modal-dialog"
            role="dialog"
            aria-labelledby="modal-label"
            aria-modal="true"
          >
            <div class="modal-header">
              <h5 id="modal-label" class="modal-title">
                Modal title
              </h5>
            </div>
            <div class="modal-body">
              <p>Modal body text goes here.</p>
            </div>
          </div>
        </div>
      </Portal>
    </div>
  );
};

🧹 When no element in the container, we will remove it for you to avoid DOM mess.

The above example shows how easy you can handle the visibility of your component. You may ask how to handle the visibility with animations? No worries, you can disable the built-in show/hide functions by setting the internalShowHide option as false then handling the visibility of your component via the isShow state.

import React from 'react';
import usePortal from 'react-cool-portal';

const App = () => {
  const { Portal, isShow, show, hide, toggle } = usePortal({
    defaultShow: false,
    internalShowHide: false, // Disable the built-in show/hide portal functions, default is true
    onShow: e => {
      // Triggered when "isShow" is set as true
    },
    onHide: e => {
      // Triggered when "isShow" is set as false
    }
  });

  return (
    <div>
      <button onClick={show}>Open Modal</button>
      <button onClick={hide}>Close Modal</button>
      <button onClick={toggle}>{isShow ? 'Close' : 'Open'} Modal</button>
      <Portal>
        <div
          // Now you can use the "isShow" state to handle the CSS animations
          class={`modal${isShow ? ' modal-open' : ''}`}
          tabIndex={-1}
        >
          <div
            class="modal-dialog"
            role="dialog"
            aria-labelledby="modal-label"
            aria-modal="true"
          >
            <div class="modal-header">
              <h5 id="modal-label" class="modal-title">
                Modal title
              </h5>
            </div>
            <div class="modal-body">
              <p>Modal body text goes here.</p>
            </div>
          </div>
        </div>
      </Portal>
    </div>
  );
};

Besides that, you can also handle the visibility of your component via React animation events or translation events like what I did for the demo app.

API

const return = usePortal(parameter);

Return object

It's returned with the following properties.

KeyTypeDefaultDescription
PortalcomponentElement(s) wrapped by the component will be rendered outside the DOM hierarchy of its parent.
isShowbooleanfalseThe show/hide state of portal.
showfunctionTo show the portal or set the isShow as true.
hidefunctionTo hide the portal or set the isShow as false.
togglefunctionTo toggle (show/hide) the portal or set the isShow as true/false.

Parameter object (optional)

When use react-cool-portal you can configure the following options via the parameter.

KeyTypeDefaultDescription
containerIdstringreact-cool-portalYou can use your own portal container by setting it as the id of the DOM element.
defaultShowbooleantrueThe initial show/hide state of the portal.
clickOutsideToHidebooleantrueHide the portal by clicking outside of it.
escToHidebooleantrueHide the portal by pressing ESC key.
internalShowHidebooleantrueEnable/disable the built-in show/hide portal functions, which gives you a flexible way to handle your portal.
onShowfunctionTriggered when portal is shown or the isShow set to true.
onHidefunctionTriggered when portal is hidden or the isShow set to false.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Welly

💻 📖 🚧

This project follows the all-contributors specification. Contributions of any kind welcome!

Keywords

FAQs

Package last updated on 21 Mar 2020

Did you know?

Socket

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.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc