diff --git a/src/index.tsx b/src/index.tsx index 4035f69..c55b786 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -31,6 +31,7 @@ interface PortalNodeBase> { // If an expected placeholder is provided, only unmount if that's still that was the // latest placeholder we replaced. This avoids some race conditions. unmount(expectedPlaceholder?: Node): void; + } export interface HtmlPortalNode = Component> extends PortalNodeBase { element: HTMLElement; @@ -159,8 +160,25 @@ class InPortal extends React.PureComponent { this.addPropsChannel(); } - componentDidUpdate() { + componentDidUpdate(previousProps: InPortalProps) { this.addPropsChannel(); + if(previousProps.node.element !== this.props.node.element){ + Object.keys(window).forEach(key => { + if (/^on/.test(key)) { + const eventType = key.slice(2); + this.props.node.element.addEventListener(eventType, this.onEventHandler); + if(previousProps.node.element){ + previousProps.node.element.removeEventListener(eventType, this.onEventHandler); + } + } + }); + + } + } + + onEventHandler(e:any){ + e.stopPropagation(); + this.props.node.element.dispatchEvent(e); } render() { diff --git a/stories/html.stories.js b/stories/html.stories.js index 1bf2986..27ed6ea 100644 --- a/stories/html.stories.js +++ b/stories/html.stories.js @@ -349,5 +349,51 @@ storiesOf('Portals', module) ; } + return + }).add('Events bubbling from PortalOut', () => { + const MyExpensiveComponent = () =>
console.log('expensive')}>expensive!
; + + const MyComponent = () => { + const portalNode = React.useMemo(() => createHtmlPortalNode(), []); + + return
+ {/* + Create the content that you want to move around. + InPortals render as normal, but to detached DOM. + Until this is used MyExpensiveComponent will not + appear anywhere in the page. + */} +
alert('InPortal wrapper click event')}> + + + +
+ + {/* ... The rest of your UI ... */} + + {/* Pass the node to whoever might want to show it: */} + +
; + } + + const ComponentA = (props) => { + return
alert('OutPortal wrapper click event')} + onMouseDown={() => console.log('Mouse Down')} + onMouseEnter={() => console.log('Mouse enter')} + > + {/* ... Some more UI ... */} + + A: + + +
; + } + return });