Socket
Socket
Sign inDemoInstall

react-useportal

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-useportal - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

2

dist/usePortal.d.ts

@@ -7,3 +7,3 @@ import { DOMAttributes, SyntheticEvent, MutableRefObject } from 'react';

targetEl: HTMLElRef;
} | SyntheticEvent<any, Event>;
} & SyntheticEvent<any, Event>;
declare type CustomEventHandler = (customEvent: CustomEvent) => void;

@@ -10,0 +10,0 @@ declare type CustomEventHandlers = {

"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {

@@ -17,18 +28,24 @@ var t = {};

Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const react_dom_1 = require("react-dom");
const use_ssr_1 = __importDefault(require("use-ssr"));
const errorMessage1 = 'You must either bind to an element or pass an event to openPortal(e).';
const stopPropagation = (e) => {
e.stopPropagation();
e.preventDefault();
var react_1 = require("react");
var react_dom_1 = require("react-dom");
var use_ssr_1 = __importDefault(require("use-ssr"));
var errorMessage1 = 'You must either bind to an element or pass an event to openPortal(e).';
var stopPropagation = function (e) {
if (e && e.nativeEvent)
e.nativeEvent.stopImmediatePropagation();
if (e)
e.stopPropagation();
if (e)
e.preventDefault();
};
function usePortal(_a = {}) {
var { closeOnOutsideClick = true, closeOnEsc = true, bindTo, // attach the portal to this node in the DOM
isOpen: defaultIsOpen = false, onOpen, onClose, onPortalClick } = _a, eventHandlers = __rest(_a, ["closeOnOutsideClick", "closeOnEsc", "bindTo", "isOpen", "onOpen", "onClose", "onPortalClick"]);
const { isServer, isBrowser } = use_ssr_1.default();
const [isOpen, makeOpen] = react_1.useState(defaultIsOpen);
function usePortal(_a) {
if (_a === void 0) { _a = {}; }
var _b = _a.closeOnOutsideClick, closeOnOutsideClick = _b === void 0 ? true : _b, _c = _a.closeOnEsc, closeOnEsc = _c === void 0 ? true : _c, bindTo = _a.bindTo, // attach the portal to this node in the DOM
_d = _a.isOpen, // attach the portal to this node in the DOM
defaultIsOpen = _d === void 0 ? false : _d, onOpen = _a.onOpen, onClose = _a.onClose, onPortalClick = _a.onPortalClick, eventHandlers = __rest(_a, ["closeOnOutsideClick", "closeOnEsc", "bindTo", "isOpen", "onOpen", "onClose", "onPortalClick"]);
var _e = use_ssr_1.default(), isServer = _e.isServer, isBrowser = _e.isBrowser;
var _f = react_1.useState(defaultIsOpen), isOpen = _f[0], makeOpen = _f[1];
// we use this ref because `isOpen` is stale for handleOutsideMouseClick
const open = react_1.useRef(isOpen);
const setOpen = react_1.useCallback((v) => {
var open = react_1.useRef(isOpen);
var setOpen = react_1.useCallback(function (v) {
// workaround to not have stale `isOpen` in the handleOutsideMouseClick

@@ -38,9 +55,9 @@ open.current = v;

}, []);
const targetEl = react_1.useRef(); // this is the element you are clicking/hovering/whatever, to trigger opening the portal
const portal = react_1.useRef(isBrowser ? document.createElement('div') : null);
react_1.useEffect(() => {
var targetEl = react_1.useRef(); // this is the element you are clicking/hovering/whatever, to trigger opening the portal
var portal = react_1.useRef(isBrowser ? document.createElement('div') : null);
react_1.useEffect(function () {
if (isBrowser && !portal.current)
portal.current = document.createElement('div');
}, [isBrowser, portal]);
const elToMountTo = react_1.useMemo(() => {
var elToMountTo = react_1.useMemo(function () {
if (isServer)

@@ -50,3 +67,10 @@ return;

}, [isServer, bindTo]);
const handleEvent = react_1.useCallback((func, event) => {
var customEvent = react_1.useCallback(function (e) {
var event = e || {};
event.portal = portal;
event.targetEl = targetEl;
event.event = e;
return event;
}, []);
var handleEvent = react_1.useCallback(function (func, event) {
if (!func || isServer)

@@ -59,12 +83,13 @@ return;

// i.e. onClick, etc. inside usePortal({ onClick({ portal, targetEl }) {} })
func(Object.assign({ portal, targetEl, event }, (event || {})));
func(customEvent(event));
}, [portal, targetEl]);
// this should handle all eventHandlers like onClick, onMouseOver, etc. passed into the config
const customEventHandlers = Object
var customEventHandlers = Object
.entries(eventHandlers)
.reduce((acc, [handlerName, eventHandler]) => {
acc[handlerName] = (event) => handleEvent(eventHandler, event);
.reduce(function (acc, _a) {
var handlerName = _a[0], eventHandler = _a[1];
acc[handlerName] = function (event) { return handleEvent(eventHandler, event); };
return acc;
}, {});
const openPortal = react_1.useCallback((event) => {
var openPortal = react_1.useCallback(function (event) {
if (isServer)

@@ -75,11 +100,9 @@ return;

// setTimeout, but for now this works
if (event)
stopPropagation(event);
if (event == null && targetEl.current == null) {
setTimeout(() => setOpen(true), 0);
setTimeout(function () { return setOpen(true); }, 0);
throw Error(errorMessage1);
}
if (event && event.nativeEvent)
event.nativeEvent.stopImmediatePropagation();
if (event)
stopPropagation(event);
if (event)
targetEl.current = event.currentTarget;

@@ -92,3 +115,3 @@ if (!targetEl.current)

}, [isServer, portal, setOpen, handleEvent, targetEl, onOpen]);
const closePortal = react_1.useCallback((event) => {
var closePortal = react_1.useCallback(function (event) {
if (isServer)

@@ -98,3 +121,3 @@ return;

stopPropagation(event);
if (onClose)
if (onClose && open.current)
handleEvent(onClose, event);

@@ -104,4 +127,6 @@ if (open.current)

}, [isServer, handleEvent, onClose, setOpen]);
const togglePortal = react_1.useCallback((e) => open.current ? closePortal(e) : openPortal(e), [closePortal, openPortal]);
const handleKeydown = react_1.useCallback(e => {
var togglePortal = react_1.useCallback(function (e) {
return open.current ? closePortal(e) : openPortal(e);
}, [closePortal, openPortal]);
var handleKeydown = react_1.useCallback(function (e) {
stopPropagation(e);

@@ -112,5 +137,3 @@ var ESC = 27;

}, [closeOnEsc, closePortal]);
const handleOutsideMouseClick = react_1.useCallback(e => {
if (!(portal.current instanceof HTMLElement))
return;
var handleOutsideMouseClick = react_1.useCallback(function (e) {
if (portal.current.contains(e.target) || e.button !== 0 || !open.current || targetEl.current.contains(e.target))

@@ -122,7 +145,9 @@ return;

}, [isServer, closePortal, closeOnOutsideClick, portal]);
const handleMouseDown = react_1.useCallback(e => {
var handleMouseDown = react_1.useCallback(function (e) {
if (isServer)
return;
stopPropagation(e);
if (onPortalClick)
if (!(portal.current instanceof HTMLElement))
return;
if (portal.current.contains(e.target) && onPortalClick)
handleEvent(onPortalClick, e);

@@ -132,4 +157,4 @@ handleOutsideMouseClick(e);

// used to remove the event listeners on unmount
const eventListeners = react_1.useRef({});
react_1.useEffect(() => {
var eventListeners = react_1.useRef({});
react_1.useEffect(function () {
if (isServer)

@@ -142,13 +167,14 @@ return;

// but for all other event handlers. For now this works.
const eventHandlerMap = {
var eventHandlerMap = {
onScroll: 'scroll',
onWheel: 'wheel',
};
const node = portal.current;
var node = portal.current;
elToMountTo.appendChild(portal.current);
// handles all special case handlers. Currently only onScroll and onWheel
Object.entries(eventHandlerMap).forEach(([handlerName /* onScroll */, eventListenerName /* scroll */]) => {
Object.entries(eventHandlerMap).forEach(function (_a) {
var handlerName = _a[0] /* onScroll */, eventListenerName = _a[1] /* scroll */;
if (!eventHandlers[handlerName])
return;
eventListeners.current[handlerName] = (e) => handleEvent(eventHandlers[handlerName], e);
eventListeners.current[handlerName] = function (e) { return handleEvent(eventHandlers[handlerName], e); };
document.addEventListener(eventListenerName, eventListeners.current[handlerName]);

@@ -158,5 +184,6 @@ });

document.addEventListener('mousedown', handleMouseDown);
return () => {
return function () {
// handles all special case handlers. Currently only onScroll and onWheel
Object.entries(eventHandlerMap).forEach(([handlerName, eventListenerName]) => {
Object.entries(eventHandlerMap).forEach(function (_a) {
var handlerName = _a[0], eventListenerName = _a[1];
if (!eventHandlers[handlerName])

@@ -172,3 +199,4 @@ return;

}, [isServer, handleOutsideMouseClick, handleKeydown, elToMountTo, portal]);
const Portal = react_1.useCallback(({ children }) => {
var Portal = react_1.useCallback(function (_a) {
var children = _a.children;
if (portal.current != null)

@@ -178,7 +206,7 @@ return react_dom_1.createPortal(children, portal.current);

}, [portal]);
return Object.assign([openPortal, closePortal, open.current, Portal, togglePortal], Object.assign(Object.assign({ isOpen: open.current, openPortal, ref: targetEl, closePortal,
togglePortal,
Portal }, customEventHandlers), { bind: Object.assign({ ref: targetEl }, customEventHandlers) }));
return Object.assign([openPortal, closePortal, open.current, Portal, togglePortal], __assign(__assign({ isOpen: open.current, openPortal: openPortal, ref: targetEl, closePortal: closePortal,
togglePortal: togglePortal,
Portal: Portal }, customEventHandlers), { bind: __assign({ ref: targetEl }, customEventHandlers) }));
}
exports.default = usePortal;
//# sourceMappingURL=usePortal.js.map
{
"name": "react-useportal",
"version": "1.0.5",
"version": "1.0.6",
"homepage": "https://codesandbox.io/s/w6jp7z4pkk",

@@ -5,0 +5,0 @@ "main": "dist/usePortal.js",

@@ -234,2 +234,3 @@ <p style="text-align: center;" align="center">

### Option Usage
```js

@@ -248,10 +249,14 @@ const {

isOpen: false,
// targetEl is the element that you either are attaching a `ref` to
// or that you are putting `openPortal` or `togglePortal` on
onOpen: ({ portal, targetEl, ...event }) => {},
// `event` has all the fields that a normal `event` would have such as `event.target.value`, etc.
onClose({ portal, targetEl, ...event }) {},
onPortalClick({ portal, targetEl, ...event }) {},
// in addition, any event handler such as onClick, onMouseOver, etc will be handled like
onClick({ event, portal, targetEl }) {}
// with the additional `portal` and `targetEl` added to it as seen in the examples below
onOpen: (event) => {
// can access: event.portal, event.targetEl, event.event, event.target, etc.
},
// `onClose` will not have an `event` unless you pass an `event` to `closePortal`
onClose({ portal, targetEl, event }) {},
// `targetEl` is the element that you either are attaching a `ref` to
// or that you are putting `openPortal` or `togglePortal` or `closePortal` on
onPortalClick({ portal, targetEl, event }) {},
// in addition, any event handler such as onClick, onMouseOver, etc will be handled the same
onClick({ portal, targetEl, event }) {}
})

@@ -258,0 +263,0 @@ ```

Sorry, the diff of this file is not supported yet

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