All Projects โ†’ wellyshen โ†’ React Cool Portal

wellyshen / React Cool Portal

Licence: mit
๐Ÿ˜Ž ๐Ÿ’ React hook for Portals, which renders modals, dropdowns, tooltips etc. to <body> or else.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Cool Portal

React Useportal
๐ŸŒ€ React hook for Portals
Stars: โœญ 698 (+52.4%)
Mutual labels:  portal, dialog, modal, dropdown, notification, tooltip, lightbox, loading-bar
react-layer-stack
Layering system for React. Useful for popover/modals/tooltip/dnd application
Stars: โœญ 158 (-65.5%)
Mutual labels:  popover, modal, lightbox, tooltip, portal, dropdown
React Layer Stack
Layering system for React. Useful for popover/modals/tooltip/dnd application
Stars: โœญ 152 (-66.81%)
Mutual labels:  portal, modal, dropdown, tooltip, lightbox, popover
toppy
Overlay library for Angular 7+
Stars: โœญ 81 (-82.31%)
Mutual labels:  popover, modal, tooltip, dropdown, toast
Ng Bootstrap
Angular powered Bootstrap
Stars: โœญ 7,872 (+1618.78%)
Mutual labels:  modal, dropdown, tooltip, popover
Jbox
jBox is a jQuery plugin that makes it easy to create customizable tooltips, modal windows, image galleries and more.
Stars: โœญ 1,251 (+173.14%)
Mutual labels:  dialog, modal, tooltip, lightbox
React Laag
Hooks to build things like tooltips, dropdown menu's and popovers in React
Stars: โœญ 568 (+24.02%)
Mutual labels:  hook, dropdown, tooltip, popover
Simplelightbox
Touch-friendly image lightbox for mobile and desktop
Stars: โœญ 744 (+62.45%)
Mutual labels:  dialog, modal, lightbox
Tippyjs React
React component for Tippy.js (official)
Stars: โœญ 1,081 (+136.03%)
Mutual labels:  dropdown, tooltip, popover
Anylayer
Android็จณๅฎš้ซ˜ๆ•ˆ็š„ๆตฎๅฑ‚ๅˆ›ๅปบ็ฎก็†ๆก†ๆžถ
Stars: โœญ 745 (+62.66%)
Mutual labels:  dialog, toast, notification
Noty
A simple library for creating animated warnings/dialogs/alerts for Android.
Stars: โœญ 136 (-70.31%)
Mutual labels:  dialog, toast, notification
Wc Messagebox
ๅŸบไบŽ Vue 2.0 ๅผ€ๅ‘็š„ Alert, Toast, Confirm ๆ’ไปถ, UIไปฟ็…ง iOS ๅŽŸ็”Ÿ
Stars: โœญ 203 (-55.68%)
Mutual labels:  dialog, modal, toast
Tippyjs
Tooltip, popover, dropdown, and menu library
Stars: โœญ 9,433 (+1959.61%)
Mutual labels:  dropdown, tooltip, popover
MultiDialog
MultiDialog utilizes jQuery UI Dialog Widget for a full featured Modalbox / Lightbox application.
Stars: โœญ 23 (-94.98%)
Mutual labels:  modal, lightbox, dialog
Popper Core
๐Ÿฟ JavaScript positioning library for tooltips, popovers, dropdowns, and more
Stars: โœญ 18,903 (+4027.29%)
Mutual labels:  dropdown, tooltip, popover
React Portal
๐ŸŽฏ React component for transportation of modals, lightboxes, loading bars... to document.body or else.
Stars: โœญ 2,023 (+341.7%)
Mutual labels:  portal, modal, loading-bar
floating-ui
A low-level toolkit to create floating elements. Tooltips, popovers, dropdowns, and more
Stars: โœญ 23,485 (+5027.73%)
Mutual labels:  popover, tooltip, dropdown
denbun
Adjust showing frequency of Android app messages, and to be more user friendly ๐Ÿฆ
Stars: โœญ 17 (-96.29%)
Mutual labels:  dialog, toast, notification
Ngx Gallery
Angular Gallery, Carousel and Lightbox
Stars: โœญ 417 (-8.95%)
Mutual labels:  modal, lightbox
Easy Toggle State
A tiny JavaScript library to easily toggle the state of any HTML element in any contexts, and create UI components in no time.
Stars: โœญ 261 (-43.01%)
Mutual labels:  dropdown, tooltip

REACT COOL PORTAL

This is a React hook for Portals. It helps you render children into a DOM node that exists outside the DOM hierarchy of the parent component. From now on you will never need to struggle with modals, dropdowns, tooltips etc. Check the features section out to learn more. 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

demo

โšก๏ธ Try yourself: https://react-cool-portal.netlify.app

Features

Requirement

To use react-cool-portal, you must use [email protected] 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 a different location in the DOM.

import usePortal from "react-cool-portal";

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

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

By default, the children of portal is rendered into <div id="react-cool-portal"> of <body>. You can specify the DOM element you want through the containerId option.

import usePortal from "react-cool-portal";

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

  return (
    <div>
      <Portal>
        <p>Now I am rendered into the specify element (id="my-portal-root").</p>
      </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. For instance, modal, dropdown, tooltip, and so on.

Edit usePortal

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(e?)"
    },
    onHide: (e) => {
      // Triggered when portal is hidden
      // The event object will be the parameter of "hide(e?)", it maybe 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 className="modal" tabIndex={-1}>
          <div
            className="modal-dialog"
            role="dialog"
            aria-labelledby="modal-label"
            aria-modal="true"
          >
            <div className="modal-header">
              <h5 id="modal-label" className="modal-title">
                Modal title
              </h5>
            </div>
            <div className="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 to false then handling the visibility of your component via the isShow state.

Edit usePortal with Animation

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 to true
    },
    onHide: (e) => {
      // Triggered when "isShow" is set to 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
          className={`modal${isShow ? " modal-open" : ""}`}
          tabIndex={-1}
        >
          <div
            className="modal-dialog"
            role="dialog"
            aria-labelledby="modal-label"
            aria-modal="true"
          >
            <div className="modal-header">
              <h5 id="modal-label" className="modal-title">
                Modal title
              </h5>
            </div>
            <div className="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 transition events like what I did for the demo app.

Build Your Customized Hook

Are you tired to write the same code over and over again? It's time to build your own hook based on react-cool-portal then use it wherever you want.

import { useCallback } from "react";
import usePortal from "react-cool-portal";

// Customize your hook based on react-cool-portal
const useModal = (options = {}) => {
  const { Portal, isShow, ...rest } = usePortal({
    ...options,
    defaultShow: false,
    internalShowHide: false,
  });

  const Modal = useCallback(
    ({ children }) => (
      <Portal>
        <div className={`modal${isShow ? " modal-open" : ""}`} tabIndex={-1}>
          {children}
        </div>
      </Portal>
    ),
    [isShow]
  );

  return { Modal, isShow, ...rest };
};

// Use it wherever you want
const App = () => {
  const { Modal, show, hide } = useModal();

  return (
    <div>
      <button onClick={show}>Open Modal</button>
      <button onClick={hide}>Close Modal</button>
      <Modal>
        <div
          className="modal-dialog"
          role="dialog"
          aria-labelledby="modal-label"
          aria-modal="true"
        >
          <div className="modal-header">
            <h5 id="modal-label" className="modal-title">
              Modal title
            </h5>
          </div>
          <div className="modal-body">
            <p>Modal body text goes here.</p>
          </div>
        </div>
      </Modal>
    </div>
  );
};

One problem of the above example is that CSS transition/animation will be cut off due to the re-creating of the Portal component. So if you want to apply transitions or animations to the wrapped element of the customized hook. The isShow need to be passed from the props.

Edit usePortal - custom

const useModal = (options = {}) => {
  const { Portal, ...rest } = usePortal({
    ...options,
    defaultShow: false,
    internalShowHide: false,
  });

  const Modal = useCallback(
    // Pass the "isShow" from props to prevent CSS transition/animation to be cut off
    ({ isShow, children }) => (
      <Portal>
        <div className={`modal${isShow ? " modal-open" : ""}`} tabIndex={-1}>
          {children}
        </div>
      </Portal>
    ),
    []
  );

  return { Modal, ...rest };
};

API

const returnObj = usePortal(parameterObj);

Return object

It's returned with the following properties.

Key Type Default Description
Portal component Renders children into a DOM node that exists outside the DOM hierarchy of the parent component.
isShow boolean false The show/hide state of portal.
show function To show the portal or set the isShow to true.
hide function To hide the portal or set the isShow to false.
toggle function To toggle (show/hide) the portal or set the isShow to true/false.

Parameter object (optional)

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

Key Type Default Description
containerId string react-cool-portal You can specify your own container id from an existing DOM element or let this hook automatically creates it for you.
defaultShow boolean true The initial show/hide state of the portal.
clickOutsideToHide boolean true Hide the portal by clicking outside of it.
escToHide boolean true Hide the portal by pressing ESC key.
internalShowHide boolean true Enable/disable the built-in show/hide portal functions, which gives you a flexible way to handle your portal.
onShow function Triggered when portal is shown or the isShow set to true.
onHide function Triggered when portal is hidden or the isShow set to false.

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Welly

๐Ÿ’ป ๐Ÿ“– ๐Ÿšง

Dawid Karabin

๐Ÿ“–

Honza Stepanovsky

๐Ÿ›

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].