Socket
Socket
Sign inDemoInstall

react-useportal

Package Overview
Dependencies
8
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.43 to 0.1.44

dist/usePortal.d.ts

77

dist/usePortal.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const react_dom_1 = require("react-dom");
const emptyFunction = () => { };
const use_ssr_1 = __importDefault(require("use-ssr"));
function usePortal({ closeOnOutsideClick = true, closeOnEsc = true, renderOnClickedElement, renderBelowClickedElement, // appear directly under the clicked element/node in the DOM
bindTo, // attach the portal to this node in the DOM
isOpen: defaultIsOpen = false, stateful = true, } = {}) {
const isBrowser = react_1.useRef(false);
react_1.useEffect(() => {
isBrowser.current = true;
return () => {
isBrowser.current = false;
};
}, []);
// if we're not on the browser, don't continue
if (!isBrowser.current)
return Object.assign([emptyFunction, emptyFunction, false, emptyFunction], {
isOpen: false,
openPortal: emptyFunction,
onMouseDown: emptyFunction,
ref: null,
closePortal: emptyFunction,
togglePortal: emptyFunction,
Portal: emptyFunction,
bind: {
onMouseDown: emptyFunction,
ref: null
}
});
const { isServer, isBrowser } = use_ssr_1.default();
const [isOpen, makeOpen] = react_1.useState(defaultIsOpen);
// we use this ref because `isOpen` is stale for handleOutsideMouseClick
const open = react_1.useRef(isOpen);

@@ -39,4 +22,12 @@ const setOpen = react_1.useCallback(v => {

const renderByRef = react_1.useRef();
const portal = react_1.useRef(document && document.createElement('div'));
const elToMountTo = react_1.useMemo(() => (bindTo && react_dom_1.findDOMNode(bindTo)) || (document && document.body), []);
const portal = react_1.useRef(isBrowser && document.createElement('div'));
react_1.useEffect(() => {
if (isBrowser && !portal.current)
portal.current = document.createElement('div');
}, [isBrowser]);
const elToMountTo = react_1.useMemo(() => {
if (isServer)
return;
return ((bindTo && react_dom_1.findDOMNode(bindTo)) || document.body);
}, [isServer, bindTo]);
const handleKeydown = react_1.useCallback(e => {

@@ -46,4 +37,6 @@ var ESC = 27;

setOpen(false);
}, []);
}, [closeOnEsc, stateful, setOpen]);
const openPortal = react_1.useCallback(e => {
if (isServer)
return;
// for some reason, when we don't have the event argument there

@@ -57,3 +50,3 @@ // is a weird race condition, would like to see if we can remove

const { left, top, height } = e.target.getBoundingClientRect();
if (renderOnClickedElement) {
if (renderOnClickedElement && portal.current instanceof HTMLElement) {
portal.current.style.height = '0px';

@@ -64,3 +57,3 @@ portal.current.style.position = 'absolute';

}
else if (renderBelowClickedElement) {
else if (renderBelowClickedElement && portal.current instanceof HTMLElement) {
portal.current.style.position = 'absolute';

@@ -71,14 +64,22 @@ portal.current.style.left = left + 'px';

stateful && setOpen(true);
}, [stateful, portal]);
}, [isServer, stateful, portal, setOpen, renderBelowClickedElement, renderOnClickedElement]);
const closePortal = react_1.useCallback(() => {
if (isServer)
return;
if (open.current)
setOpen(false);
}, [isOpen, open.current]);
}, [isServer, isOpen, open.current, setOpen]);
const togglePortal = react_1.useCallback(e => (isOpen ? setOpen(false) : openPortal(e)), [isOpen, open.current, setOpen, openPortal]);
const handleOutsideMouseClick = react_1.useCallback(({ target, button }) => {
if (portal.current.contains(target) || button !== 0 || !portal.current || !open.current)
if (isServer || !(portal.current instanceof HTMLElement))
return;
if (portal.current.contains(target) || button !== 0 || !open.current)
return;
if (stateful && closeOnOutsideClick)
closePortal();
}, [isOpen]);
}, [isServer, isOpen, stateful, closePortal, closeOnOutsideClick]);
react_1.useEffect(() => {
if (isServer || !(elToMountTo instanceof HTMLElement) || !(portal.current instanceof HTMLElement))
return;
const node = portal.current;
elToMountTo.appendChild(portal.current);

@@ -90,7 +91,10 @@ document && document.addEventListener('keydown', handleKeydown);

document && document.removeEventListener('click', handleOutsideMouseClick);
elToMountTo.removeChild(portal.current);
elToMountTo.removeChild(node);
};
}, [handleOutsideMouseClick, handleKeydown]);
const togglePortal = react_1.useCallback(e => isOpen ? setOpen(false) : openPortal(e), [isOpen, open.current]);
const Portal = ({ children }) => react_dom_1.createPortal(children, portal.current);
}, [isServer, handleOutsideMouseClick, handleKeydown, elToMountTo]);
const Portal = ({ children }) => {
if (portal.current instanceof HTMLElement)
return react_dom_1.createPortal(children, portal.current);
return null;
};
return Object.assign([

@@ -116,4 +120,3 @@ openPortal,

}
exports.usePortal = usePortal;
exports.default = usePortal;
//# sourceMappingURL=usePortal.js.map
{
"name": "react-useportal",
"version": "0.1.43",
"version": "0.1.44",
"homepage": "https://codesandbox.io/s/w6jp7z4pkk",

@@ -24,3 +24,4 @@ "main": "dist/usePortal.js",

"parcel-bundler": "^1.12.3",
"typescript": "^3.4.5"
"typescript": "^3.4.5",
"use-ssr": "^1.0.13"
},

@@ -30,4 +31,8 @@ "scripts": {

"build": "rm -rf dist && ./node_modules/.bin/tsc --module CommonJS",
"publish": "yarn build && yarn publish"
"prepublish": "yarn build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"files": [
"dist"
],
"keywords": [

@@ -34,0 +39,0 @@ "react",

@@ -152,5 +152,6 @@ <p style="text-align: center;" align="center">

```
- [X] make isomorphic
- [ ] tests (priority)
- [ ] see if it's reliable to rely on react's internals for determining whether we're on the server or not. [Here](https://github.com/JedWatson/exenv) it says not to, but that was also 3 years ago.
- [ ] make work without requiring the html synthetic event & document when you are required to have it and when you are not
- [ ] clean up code
- [X] make isomorphic
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc