eventStack: Multiple Popups do not behave correctly
See original GitHub issueI have some popups like this in my project (this is a simplified version with the important bits):
class SomePopup extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false
};
this.close = this.close.bind(this);
this.open = this.open.bind(this);
}
close() {
this.setState({ open: false });
}
open() {
this.setState({ open: true });
}
render() {
const { /*Destructured props*/, ...rest } = this.props;
return (
<Popup
{...rest}
onClose={e => {
this.close();
// do something with a prop method
}}
onOpen={e => {
this.open();
// do something with a prop method
}}
trigger={
<SomeButton
onClick={e => {
// do something with a prop method
}}
active={this.state.open}
/>
}
on="click"
>
<div>Hello</div>
</Popup>
);
}
}
Where SomeButton
is a stateless button component.
As you can see the Popup is not controlled by its parent, it’s left to its default behaviour (i.e. click outside to close) and when it opens or closes, the SomePopup
’s state will update accordingly in order to reflect the fact to the button that triggered the Popup, and have it stay in “active” state as long as its popup is open.
Now, I have noticed that Popups will close when you click outside, however they will not close when you click a button that opens another popup.
Am I doing something wrong with the Popups or is this some kind of bug?
Steps
Assume we have Popup A and Popup B that are implemented as shown above.
Do the following in this order:
- Click on Popup A’s trigger button
- Click on Popup B’s trigger button
Expected Result
I would expect that once I click on the trigger of Popup B then Popup A would close and Popup B would open
Actual Result
When the Popup A is open, and you click on the trigger component of Popup B the following will happen in this order:
- The
onClick
handler of the Popup B’s trigger component will execute first - Then the
onOpen
of Popup B will execute - Then immediately after, the
onClose
handler of Popup B will execute .
As a result it looks like as if Popup B did not open at all, when in reality, it opened and closed immediately. It makes no sense for Popup B’s onClose
to fire immediately after it was opened.
In contrast, when Popup A is open, and you click outside of it (not on the trigger of Popup B) the following will happen in this order:
- First the
onClick
handler on Popup A’s trigger component will execute - Then Popup A’s
onClose
handler will execute .
I have the feeling that the Portal component used, does not keep proper track of the Popups it has open, and while it’s supposed to close the previous Popup it closes the new one
Version
0.72.0
Testcase
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:14 (14 by maintainers)
Top GitHub Comments
No, it’s bug and it will be resolved by #2117.
Ok, but, thing is it throws on class based triggers too. Is that expected?