react-useportal
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -6,5 +6,5 @@ import { DOMAttributes, SyntheticEvent, MutableRefObject } from 'react'; | ||
portal: HTMLElRef; | ||
targetEl: HTMLElement; | ||
}; | ||
declare type CustomEventHandler = (customEvent: CustomEvent) => void | HTMLElRef; | ||
targetEl: HTMLElRef; | ||
} | SyntheticEvent<any, Event>; | ||
declare type CustomEventHandler = (customEvent: CustomEvent) => void; | ||
declare type CustomEventHandlers = { | ||
@@ -20,5 +20,6 @@ [K in keyof DOMAttributes<K>]?: CustomEventHandler; | ||
onClose?: CustomEventHandler; | ||
onPortalClick?: CustomEventHandler; | ||
} & CustomEventHandlers; | ||
export default function usePortal({ closeOnOutsideClick, closeOnEsc, bindTo, // attach the portal to this node in the DOM | ||
isOpen: defaultIsOpen, onOpen, onClose, ...eventHandlers }?: UsePortalOptions): any; | ||
isOpen: defaultIsOpen, onOpen, onClose, onPortalClick, ...eventHandlers }?: UsePortalOptions): any; | ||
export {}; |
@@ -21,5 +21,9 @@ "use strict"; | ||
const errorMessage1 = 'You must either bind to an element or pass an event to openPortal(e).'; | ||
const stopPropagation = (e) => { | ||
e.stopPropagation(); | ||
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 } = _a, eventHandlers = __rest(_a, ["closeOnOutsideClick", "closeOnEsc", "bindTo", "isOpen", "onOpen", "onClose"]); | ||
isOpen: defaultIsOpen = false, onOpen, onClose, onPortalClick } = _a, eventHandlers = __rest(_a, ["closeOnOutsideClick", "closeOnEsc", "bindTo", "isOpen", "onOpen", "onClose", "onPortalClick"]); | ||
const { isServer, isBrowser } = use_ssr_1.default(); | ||
@@ -50,4 +54,6 @@ const [isOpen, makeOpen] = react_1.useState(defaultIsOpen); | ||
targetEl.current = event.currentTarget; | ||
if (event) | ||
stopPropagation(event); | ||
// i.e. onClick, etc. inside usePortal({ onClick({ portal, targetEl }) {} }) | ||
func({ portal, targetEl: targetEl.current, event }); | ||
func(Object.assign({ portal, targetEl, event }, (event || {}))); | ||
}, [portal, targetEl]); | ||
@@ -67,2 +73,4 @@ // this should handle all eventHandlers like onClick, onMouseOver, etc. passed into the config | ||
// setTimeout, but for now this works | ||
if (event) | ||
stopPropagation(event); | ||
if (event == null && targetEl.current == null) { | ||
@@ -85,2 +93,4 @@ setTimeout(() => setOpen(true), 0); | ||
return; | ||
if (event) | ||
stopPropagation(event); | ||
if (onClose) | ||
@@ -93,2 +103,3 @@ handleEvent(onClose, event); | ||
const handleKeydown = react_1.useCallback(e => { | ||
stopPropagation(e); | ||
var ESC = 27; | ||
@@ -99,4 +110,2 @@ if (e.keyCode === ESC && closeOnEsc) | ||
const handleOutsideMouseClick = react_1.useCallback(e => { | ||
if (isServer) | ||
return; | ||
if (!(portal.current instanceof HTMLElement)) | ||
@@ -106,5 +115,14 @@ return; | ||
return; | ||
stopPropagation(e); | ||
if (closeOnOutsideClick) | ||
closePortal(e); | ||
}, [isServer, closePortal, closeOnOutsideClick, portal]); | ||
const handleMouseDown = react_1.useCallback(e => { | ||
if (isServer) | ||
return; | ||
stopPropagation(e); | ||
if (onPortalClick) | ||
handleEvent(onPortalClick, e); | ||
handleOutsideMouseClick(e); | ||
}, [handleOutsideMouseClick]); | ||
// used to remove the event listeners on unmount | ||
@@ -134,3 +152,3 @@ const eventListeners = react_1.useRef({}); | ||
document.addEventListener('keydown', handleKeydown); | ||
document.addEventListener('mousedown', handleOutsideMouseClick); | ||
document.addEventListener('mousedown', handleMouseDown); | ||
return () => { | ||
@@ -145,3 +163,3 @@ // handles all special case handlers. Currently only onScroll and onWheel | ||
document.removeEventListener('keydown', handleKeydown); | ||
document.removeEventListener('mousedown', handleOutsideMouseClick); | ||
document.removeEventListener('mousedown', handleMouseDown); | ||
elToMountTo.removeChild(node); | ||
@@ -148,0 +166,0 @@ }; |
{ | ||
"name": "react-useportal", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"homepage": "https://codesandbox.io/s/w6jp7z4pkk", | ||
@@ -35,6 +35,6 @@ "main": "dist/usePortal.js", | ||
"dependencies": { | ||
"use-ssr": "^1.0.13" | ||
"use-ssr": "^1.0.19" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/react-hooks": "^2.0.1", | ||
"@testing-library/react-hooks": "^3.0.0", | ||
"@types/jest": "^24.0.18", | ||
@@ -41,0 +41,0 @@ "@types/react": "^16.9.2", |
@@ -159,6 +159,7 @@ <p style="text-align: center;" align="center"> | ||
/* add your css here for the Portal */ | ||
position: absolute; | ||
position: fixed; | ||
left: 50%; | ||
top: 50%; | ||
transform: translate(-50%,-50%); | ||
z-index: 1000; | ||
` | ||
@@ -230,2 +231,3 @@ } | ||
| `onClose` | This is used to call something when the portal is closed and to modify the css of the portal directly | | ||
| `onPortalClick` | This is fired whenever clicking on the `Portal` | | ||
| html event handlers (i.e. `onClick`) | These can be used instead of `onOpen` to modify the css of the portal directly. [`onMouseEnter` and `onMouseLeave` example](https://codesandbox.io/s/useportal-usedropdown-dgesf) | | ||
@@ -247,4 +249,8 @@ | ||
isOpen: false, | ||
onOpen: ({ event, portal, targetEl }) => {}, | ||
onClose({ event, portal, targetEl }) {}, | ||
// 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 | ||
@@ -256,3 +262,11 @@ onClick({ event, portal, targetEl }) {} | ||
------ | ||
- [ ] maybe disable scrolling outside of the portal when it is open? | ||
- [ ] React Native support. [1](https://github.com/zenyr/react-native-portal) [2](https://github.com/cloudflare/react-gateway) [3](https://medium.com/@naorzruk/portals-in-react-native-22797ba8aa1b) [4](https://stackoverflow.com/questions/46505378/can-we-have-react-16-portal-functionality-react-native) [5](https://github.com/callstack/react-native-paper/blob/master/src/components/Portal/PortalManager.tsx) Probably going to have to add a `Provider`... | ||
- [ ] add correct return types | ||
- [ ] add a `Provider` for `useModal`. Potential syntax ideas | ||
```js | ||
const App = ( | ||
<Provider background='rgba(0, 0, 0, 0.75)' animation=''><Root /></Provider> | ||
) | ||
``` | ||
- [ ] add support for popup windows [resource 1](https://javascript.info/popup-windows) [resource 2](https://hackernoon.com/using-a-react-16-portal-to-do-something-cool-2a2d627b0202). Maybe something like | ||
@@ -259,0 +273,0 @@ ```jsx |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
29590
191
282
Updateduse-ssr@^1.0.19