Need to make dropdowns, lightboxes/modals/dialogs, global message notifications, or tooltips in React? React Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component (react docs).
This hook is also isomorphic, meaning it works with SSR (server side rendering).
Features -------- - SSR (server side rendering) support - TypeScript support - 1 dependency (use-ssr) - Built in state
This Portal handles its own state.{' '} , hit ESC or click outside of me.
> ) }
`
$3
By using onOpen, onClose or any other event handler, you can modify the Portal and return it. See useDropdown for a working example. If opening the portal from a click event it's important that you pass the event object to openPortal and togglePortal otherwise you will need to attach a ref to the clicked element (if you want to be able to open the portal without passing an event you will need to set programmaticallyOpen to true).`jsx const useModal = () => { const { isOpen, openPortal, togglePortal, closePortal, Portal } = usePortal({ onOpen({ portal }) { portal.current.style.cssText = / add your css here for the Portal / position: fixed; left: 50%; top: 50%; transform: translate(-50%,-50%); z-index: 1000; } })
Make sure you are passing the html synthetic event to the
openPortal and togglePortal . i.e. onClick={e => openPortal(e)}
$3
If for some reason, you don't want to pass around the event to openPortal or togglePortal and you're not using programmaticallyOpen, you can use a ref like this. `jsx import usePortal from 'react-useportal'
closeOnOutsideClick | This will close the portal when not clicking within the portal. Default is true | | closeOnEsc | This will allow you to hit ESC and it will close the modal. Default is true | | bindTo | This is the DOM node you want to attach the portal to. By default it attaches to document.body | | isOpen | This will be the default for the portal. Default is false | | onOpen | This is used to call something when the portal is opened and to modify the css of the portal directly | | 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 | | programmaticallyOpen | This option allows you to open or toggle the portal without passing in an event. Default is false |
$3
`js const { openPortal, closePortal, togglePortal, isOpen, Portal, // if you don't pass an event to openPortal, closePortal, or togglePortal and you're not using programmaticallyOpen, you will need // to put this on the element you want to interact with/click ref, // if for some reason you want to interact directly with the portal, you can with this ref portalRef, } = usePortal({ closeOnOutsideClick: true, closeOnEsc: true, bindTo, // attach the portal to this node in the DOM isOpen: false, // event has all the fields that a normal event would have such as event.target.value, etc. // 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 }) {} }) ` Todos ------ - [ ] React Native support. 12345 Probably going to have to add a Provider... - [ ] add correct typescript return types - [ ] add support for popup windows resource 1resource 2. Maybe something like `jsx const { openPortal, closePortal, isOpen, Portal } = usePortal({ popup: ['', '', 'width=600,height=400,left=200,top=200'] }) // window.open('', '', 'width=600,height=400,left=200,top=200') ` - [ ] tests (priority) - [ ] maybe have a ` then you can change the order of the array destructuring syntax - [ ] fix code so maintainability is A - [ ] set up code climate test coverage - [ ] optimize badges see awesome badge list - [ ] add code climate test coverage badge