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 - npm Package Compare versions

Comparing version 0.0.16 to 0.1.0

11

dist/index.d.ts

@@ -18,6 +18,7 @@ declare module 'react-cool-portal' {

defaultShow?: boolean;
clickOutsideToHide?: boolean;
escToHide?: boolean;
internalShowHide?: boolean;
onShow?: RCPF;
onHide?: RCPF<ReactMouseEvent | MouseEvent | KeyboardEvent>;
clickOutsideToHide?: boolean;
escToHide?: boolean;
}

@@ -36,6 +37,6 @@

defaultShow,
clickOutsideToHide,
escToHide,
onShow,
onHide,
clickOutsideToHide,
escToHide
onHide
}?: Args) => Return;

@@ -42,0 +43,0 @@

@@ -1,1 +0,1 @@

import{useState as n,useEffect as t,useRef as e,useCallback as r,useMemo as o}from"react";import{createPortal as i}from"react-dom";function u(n,t){return function(n){if(Array.isArray(n))return n}(n)||function(n,t){if(!(Symbol.iterator in Object(n)||"[object Arguments]"===Object.prototype.toString.call(n)))return;var e=[],r=!0,o=!1,i=void 0;try{for(var u,c=n[Symbol.iterator]();!(r=(u=c.next()).done)&&(e.push(u.value),!t||e.length!==t);r=!0);}catch(n){o=!0,i=n}finally{try{r||null==c.return||c.return()}finally{if(o)throw i}}return e}(n,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}var c=function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,e=setTimeout((function(){clearTimeout(e),n()}),t)},a=function(e,r,o,a){return function(d){var f=d.children,l=u(n(null),2),v=l[0],m=l[1];return t((function(){return m(document.getElementById(e)||function(n){var t=document.createElement("div");return t.setAttribute("id",n),document.body.appendChild(t),t}(e)),function(){v&&c((function(){""===v.innerHTML&&v.remove()}))}}),[v]),t((function(){if((o||a)&&r&&v){var n=function(n){v.contains(n.target)||o(n)},t=function(n){27===n.keyCode&&a(n)};return o&&document.addEventListener("click",n),a&&document.addEventListener("keydown",t),function(){o&&document.removeEventListener("click",n),a&&document.removeEventListener("keydown",t)}}}),[v]),r&&v&&i(f,v)}};export default function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},d=i.containerId,f=void 0===d?"react-cool-portal":d,l=i.defaultShow,v=void 0===l||l,m=i.onShow,s=i.onHide,y=i.clickOutsideToHide,h=void 0===y||y,p=i.escToHide,g=void 0===p||p,w=n(v),b=u(w,2),E=b[0],k=b[1],S=e(!1),T=e(null),L=e(null);t((function(){m&&(T.current=m)}),[m]),t((function(){s&&(L.current=s)}),[s]);var A=r((function(){h&&E&&(S.current=!0,c((function(){S.current=!1})))}),[h,E]),H=r((function(n){A(),E||(k(!0),m&&m(n))}),[A,E,m]),j=r((function(n){A(),E&&(k(!1),s&&s(n))}),[A,E,s]),I=r((function(n){E?j(n):H(n)}),[E,j,H]),O=r((function(n){S.current||j(n)}),[j]),x=o((function(){return a(f,E,h&&O,g&&O)}),[f,E,h,g,O]);return{Portal:x,isShow:E,show:H,hide:j,toggle:I}}
import{useState as n,useEffect as t,useRef as e,useCallback as r,useMemo as o}from"react";import{createPortal as i}from"react-dom";function u(n,t){return function(n){if(Array.isArray(n))return n}(n)||function(n,t){if(!(Symbol.iterator in Object(n)||"[object Arguments]"===Object.prototype.toString.call(n)))return;var e=[],r=!0,o=!1,i=void 0;try{for(var u,c=n[Symbol.iterator]();!(r=(u=c.next()).done)&&(e.push(u.value),!t||e.length!==t);r=!0);}catch(n){o=!0,i=n}finally{try{r||null==c.return||c.return()}finally{if(o)throw i}}return e}(n,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}var c=function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,e=setTimeout((function(){clearTimeout(e),n()}),t)},d=function(e,r,o,d){return function(a){var l=a.children,f=u(n(null),2),v=f[0],m=f[1];return t((function(){return m(document.getElementById(e)||function(n){var t=document.createElement("div");return t.setAttribute("id",n),document.body.appendChild(t),t}(e)),function(){v&&c((function(){""===v.innerHTML&&v.remove()}))}}),[v]),t((function(){if((o||d)&&r&&v){var n=function(n){v.contains(n.target)||o(n)},t=function(n){27===n.keyCode&&d(n)};return o&&document.addEventListener("click",n),d&&document.addEventListener("keydown",t),function(){o&&document.removeEventListener("click",n),d&&document.removeEventListener("keydown",t)}}}),[v]),r&&v&&i(l,v)}};export default function(){var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=i.containerId,l=void 0===a?"react-cool-portal":a,f=i.defaultShow,v=void 0===f||f,m=i.clickOutsideToHide,s=void 0===m||m,h=i.escToHide,y=void 0===h||h,p=i.internalShowHide,w=void 0===p||p,g=i.onShow,b=i.onHide,E=n(v),S=u(E,2),k=S[0],T=S[1],H=e(!1),L=e(null),A=e(null);t((function(){g&&(L.current=g)}),[g]),t((function(){b&&(A.current=b)}),[b]);var j=r((function(){s&&k&&(H.current=!0,c((function(){H.current=!1})))}),[s,k]),I=r((function(n){j(),k||(T(!0),g&&g(n))}),[j,k,g]),O=r((function(n){j(),k&&(T(!1),b&&b(n))}),[j,k,b]),x=r((function(n){k?O(n):I(n)}),[k,O,I]),C=r((function(n){H.current||O(n)}),[O]),P=o((function(){return d(l,!w||k,s&&C,y&&C)}),[l,w,k,s,y,C]);return{Portal:P,isShow:k,show:I,hide:O,toggle:x}}

@@ -1,1 +0,1 @@

"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react-dom");function n(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(!(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)))return;var n=[],r=!0,o=!1,u=void 0;try{for(var c,i=e[Symbol.iterator]();!(r=(c=i.next()).done)&&(n.push(c.value),!t||n.length!==t);r=!0);}catch(e){o=!0,u=e}finally{try{r||null==i.return||i.return()}finally{if(o)throw u}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}var r=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,n=setTimeout((function(){clearTimeout(n),e()}),t)},o=function(o,u,c,i){return function(a){var l=a.children,f=n(e.useState(null),2),d=f[0],s=f[1];return e.useEffect((function(){return s(document.getElementById(o)||function(e){var t=document.createElement("div");return t.setAttribute("id",e),document.body.appendChild(t),t}(o)),function(){d&&r((function(){""===d.innerHTML&&d.remove()}))}}),[d]),e.useEffect((function(){if((c||i)&&u&&d){var e=function(e){d.contains(e.target)||c(e)},t=function(e){27===e.keyCode&&i(e)};return c&&document.addEventListener("click",e),i&&document.addEventListener("keydown",t),function(){c&&document.removeEventListener("click",e),i&&document.removeEventListener("keydown",t)}}}),[d]),u&&d&&t.createPortal(l,d)}};exports.default=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},u=t.containerId,c=void 0===u?"react-cool-portal":u,i=t.defaultShow,a=void 0===i||i,l=t.onShow,f=t.onHide,d=t.clickOutsideToHide,s=void 0===d||d,v=t.escToHide,m=void 0===v||v,y=e.useState(a),b=n(y,2),h=b[0],k=b[1],p=e.useRef(!1),E=e.useRef(null),g=e.useRef(null);e.useEffect((function(){l&&(E.current=l)}),[l]),e.useEffect((function(){f&&(g.current=f)}),[f]);var w=e.useCallback((function(){s&&h&&(p.current=!0,r((function(){p.current=!1})))}),[s,h]),S=e.useCallback((function(e){w(),h||(k(!0),l&&l(e))}),[w,h,l]),C=e.useCallback((function(e){w(),h&&(k(!1),f&&f(e))}),[w,h,f]),T=e.useCallback((function(e){h?C(e):S(e)}),[h,C,S]),L=e.useCallback((function(e){p.current||C(e)}),[C]),j=e.useMemo((function(){return o(c,h,s&&L,m&&L)}),[c,h,s,m,L]);return{Portal:j,isShow:h,show:S,hide:C,toggle:T}};
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("react-dom");function n(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(!(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)))return;var n=[],r=!0,o=!1,u=void 0;try{for(var i,c=e[Symbol.iterator]();!(r=(i=c.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){o=!0,u=e}finally{try{r||null==c.return||c.return()}finally{if(o)throw u}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}var r=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:100,n=setTimeout((function(){clearTimeout(n),e()}),t)},o=function(o,u,i,c){return function(a){var l=a.children,f=n(e.useState(null),2),d=f[0],s=f[1];return e.useEffect((function(){return s(document.getElementById(o)||function(e){var t=document.createElement("div");return t.setAttribute("id",e),document.body.appendChild(t),t}(o)),function(){d&&r((function(){""===d.innerHTML&&d.remove()}))}}),[d]),e.useEffect((function(){if((i||c)&&u&&d){var e=function(e){d.contains(e.target)||i(e)},t=function(e){27===e.keyCode&&c(e)};return i&&document.addEventListener("click",e),c&&document.addEventListener("keydown",t),function(){i&&document.removeEventListener("click",e),c&&document.removeEventListener("keydown",t)}}}),[d]),u&&d&&t.createPortal(l,d)}};exports.default=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},u=t.containerId,i=void 0===u?"react-cool-portal":u,c=t.defaultShow,a=void 0===c||c,l=t.clickOutsideToHide,f=void 0===l||l,d=t.escToHide,s=void 0===d||d,v=t.internalShowHide,m=void 0===v||v,y=t.onShow,h=t.onHide,b=e.useState(a),k=n(b,2),p=k[0],E=k[1],w=e.useRef(!1),g=e.useRef(null),S=e.useRef(null);e.useEffect((function(){y&&(g.current=y)}),[y]),e.useEffect((function(){h&&(S.current=h)}),[h]);var C=e.useCallback((function(){f&&p&&(w.current=!0,r((function(){w.current=!1})))}),[f,p]),T=e.useCallback((function(e){C(),p||(E(!0),y&&y(e))}),[C,p,y]),H=e.useCallback((function(e){C(),p&&(E(!1),h&&h(e))}),[C,p,h]),L=e.useCallback((function(e){p?H(e):T(e)}),[p,H,T]),j=e.useCallback((function(e){w.current||H(e)}),[H]),A=e.useMemo((function(){return o(i,!m||p,f&&j,s&&j)}),[i,m,p,f,s,j]);return{Portal:A,isShow:p,show:T,hide:H,toggle:L}};
{
"name": "react-cool-portal",
"version": "0.0.16",
"version": "0.1.0",
"description": "React hook for Portals, which renders modals, dropdowns, tooltips etc. to <body> or else.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -20,2 +20,4 @@ > ⚠️ 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](https://github.com/wellyshen/react-cool-portal/releases) for any change. Here's the [milestone](#milestone).

## Live Demo
![portal_modal](https://user-images.githubusercontent.com/21308003/76686161-6ff78580-6654-11ea-916b-117c85862711.gif)

@@ -32,2 +34,3 @@

- [x] Support clickOutsideToHide and escToHide interactions
- [x] Provide a flexible way to handle animations
- [x] Server-side rendering compatibility

@@ -57,2 +60,4 @@ - [ ] Unit testing

Here are some minimal examples of how does it work. You can learn more about it by checking the [API](#api) out.
### Basic Use Case

@@ -81,3 +86,3 @@

By default, the children of the `Portal` is rendered into `<div id="react-cool-portal">` of `<body>`. You can use your own container element by the `containerId` option.
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.

@@ -113,13 +118,10 @@ ```js

const { Portal, isShow, show, hide, toggle } = usePortal({
containerId: 'my-portal-root',
defaultShow: false, // Default is true.
clickOutsideToHide: true, // Default is true.
escToHide: true, // Default is true.
defaultShow: false, // The default visibility of portal, default is true
onShow: e => {
// Triggered on show portal.
// The event object will be MouseEvent, KeyboardEvent, Your custom event. Depends on your interaction.
// Triggered when portal is shown
// The event object will be the parameter of "show()"
},
onHide: e => {
// Triggered on hide portal.
// The event object will be MouseEvent, KeyboardEvent, Your custom event. Depends on your interaction.
// Triggered when portal is hidden
// The event object will be the parameter of "hide()", MouseEvent (on clicks outside) or KeyboardEvent (press ESC key)
}

@@ -134,5 +136,5 @@ });

<Portal>
<div class="modal-backdrop" tabIndex={-1}>
<div class="modal" tabIndex={-1}>
<div
class="modal"
class="modal-dialog"
role="dialog"

@@ -160,2 +162,87 @@ aria-labelledby="modal-label"

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.
```js
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](https://reactjs.org/docs/events.html#animation-events) or [translation events](https://reactjs.org/docs/events.html#transition-events) like [what I did](https://github.com/wellyshen/react-cool-portal/blob/master/demo/App/index.tsx) for the [demo app](#live-demo).
## API
```js
const return = usePortal(parameter);
```
### Return object
It's returned with the following properties.
| Key | Type | Default | Description |
| ------ | --------- | ------- | --------------------------------------------------------------------------------------------- |
| Portal | component | | Element(s) wrapped by the component will be rendered outside the DOM hierarchy of its parent. |
| isShow | boolean | `false` | The show/hide state of portal. |
| show | function | | To show the portal or set the `isShow` as `true`. |
| hide | function | | To hide the portal or set the `isShow` as `false`. |
| toggle | function | | To 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.
| Key | Type | Default | Description |
| ------------------ | -------- | ------------------- | --------------------------------------------------------------------------------------------------------------- |
| containerId | string | `react-cool-portal` | You can use your own portal container by setting it as the id of the DOM element. |
| 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 ✨

@@ -162,0 +249,0 @@

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