Skip to content

Commit cae9bf9

Browse files
committed
Test onClick
1 parent 3426281 commit cae9bf9

File tree

2 files changed

+81
-7
lines changed

2 files changed

+81
-7
lines changed

src/index.tsx

+18-7
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ class InPortal extends React.PureComponent<InPortalProps, { nodeProps: {} }> {
144144
this.state = {
145145
nodeProps: this.props.node.getInitialPortalProps(),
146146
};
147+
this.onClick = this.onClick.bind(this);
147148
}
148149

149150
addPropsChannel = () => {
@@ -163,16 +164,26 @@ class InPortal extends React.PureComponent<InPortalProps, { nodeProps: {} }> {
163164
this.addPropsChannel();
164165
}
165166

167+
onClick(e:any){
168+
e.stopPropagation();
169+
console.log('click outer', this.props.node.element);
170+
this.props.node.element.dispatchEvent(new Event('click', { bubbles: true }));
171+
}
172+
166173
render() {
167174
const { children, node } = this.props;
168175

169-
return ReactDOM.createPortal(
170-
React.Children.map(children, (child) => {
171-
if (!React.isValidElement(child)) return child;
172-
return React.cloneElement(child, this.state.nodeProps)
173-
}),
174-
node.element
175-
);
176+
return <div id="outer" onClick={this.onClick}>
177+
{
178+
ReactDOM.createPortal(
179+
React.Children.map(children, (child) => {
180+
if (!React.isValidElement(child)) return child;
181+
return React.cloneElement(child, this.state.nodeProps)
182+
}),
183+
node.element
184+
)
185+
}
186+
</div>
176187
}
177188
}
178189

stories/html.stories.js

+63
Original file line numberDiff line numberDiff line change
@@ -349,5 +349,68 @@ storiesOf('Portals', module)
349349
</div>;
350350
}
351351

352+
return <MyComponent componentToShow='component-a' />
353+
}).add('Events bubbling from PortalOut', () => {
354+
const MyExpensiveComponent = () => <div onClick={() => console.log('expensive')}>expensive!</div>;
355+
356+
const MyComponent = (props) => {
357+
const portalNode = React.useMemo(() => createHtmlPortalNode(), []);
358+
359+
return <div>
360+
{/*
361+
Create the content that you want to move around.
362+
InPortals render as normal, but to detached DOM.
363+
Until this is used MyExpensiveComponent will not
364+
appear anywhere in the page.
365+
*/}
366+
<InPortal node={portalNode}>
367+
<MyExpensiveComponent
368+
// Optionally provide props to use before this enters the DOM
369+
myProp={"defaultValue"}
370+
/>
371+
</InPortal>
372+
373+
{/* ... The rest of your UI ... */}
374+
375+
{/* Pass the node to whoever might want to show it: */}
376+
{ props.componentToShow === 'component-a'
377+
? <ComponentA portalNode={portalNode} />
378+
: <ComponentB portalNode={portalNode} /> }
379+
</div>;
380+
}
381+
382+
const ComponentA = (props) => {
383+
const alertEvent = () => alert('Div clicked')
384+
return <div onClick={alertEvent}>
385+
{/* ... Some more UI ... */}
386+
387+
A:
388+
389+
<OutPortal
390+
node={props.portalNode} // Show the content from this node here
391+
/>
392+
</div>;
393+
}
394+
395+
const ComponentB = (props) => {
396+
const alertEvent = () => alert('Div clicked')
397+
return <div onClick={alertEvent}>
398+
{/* ... Some more UI ... */}
399+
400+
B:
401+
402+
<OutPortal
403+
node={props.portalNode} // Pull in the content from this node
404+
405+
myProp={"newValue"} // Optionally, override default values
406+
myOtherProp={123} // Or add new props
407+
408+
// These props go back to the InPortal, and trigger a component
409+
// update (but on the same component instance) as if they had
410+
// been passed directly.
411+
/>
412+
</div>;
413+
}
414+
352415
return <MyComponent componentToShow='component-a' />
353416
});

0 commit comments

Comments
 (0)