-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(Modal|Popup|Portal): fix usage of eventStack sub/unsub #2099
fix(Modal|Popup|Portal): fix usage of eventStack sub/unsub #2099
Conversation
Codecov Report
@@ Coverage Diff @@
## master #2099 +/- ##
==========================================
+ Coverage 99.76% 99.76% +<.01%
==========================================
Files 149 149
Lines 2598 2599 +1
==========================================
+ Hits 2592 2593 +1
Misses 6 6
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@austinfox thanks for picking up this 👍
Proposed changes useless, because in fact it's equals to default
pool of the eventStack
. My initial proposal about the exclusive
prop is also not ideal.
Problem
We have a couple of bugs with multiple Modal
s, eventStack
solves them and improves performance.
What eventStack
actually does? It has an entity called pool
. Event handlers that included in default
pool will be fired usual. But, only the last added event handler to the named pool will be fired when corresponding event will be occured.
You can open this Modal
example. Open both modals and then press Esc
key. Only top modal will be closed and it's correct. But, as we can see it causes problems for Popup
s.
Solution
So, my idea is to add the eventPool
prop to the Portal
which defaults to default
:
const { eventPool } = this.props
eventStack.sub('keydown', this.handleEscape, eventPool)
This prop should be also added to Modal
and Popup
, where it will be defaults to Modal
and default
accordingly. It will keep Modal
working correctly and solve the problem with event propagation in Popup
.
Let me know what you think.
@layershifter Yea I was thinking about adding a prop to Modal, Popup, and Portal. I'm not convinced it will be clear to others how to prevent this bug though even if we add eventPool as a prop. If they have an in-depth knowledge about the inner workings of Portal and eventStack, then yes they will be able to fix the problem. But by default, clicking on a popup and then clicking on another popup will be broken. Why not default to having each Popup use its own eventPool? I think that is standard behavior, whenever you click away from a popup is should almost always close. |
@layershifter ignore my last comment. Taking a look at the EventStack code, I now understand what you mean. When the 'default' poolName is used, all handlers are called for that event. This will work just fine, I'll modify the PR in a few hours. Is there any way we can get this change into a new version of SUI react asap? My team site is currently breaking for IE users because we cannot use this feature. I had to rely on='focus' and do some other hacks that work well for chrome, Firefox, safari, and edge, but... sigh, IE... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. I left some comments about styling.
src/addons/Portal/Portal.js
Outdated
@@ -115,6 +115,9 @@ class Portal extends Component { | |||
/** Controls whether or not the portal should open when mousing over the trigger. */ | |||
openOnTriggerMouseEnter: PropTypes.bool, | |||
|
|||
/** Event pool namespace that is used to handle component events */ | |||
eventPool: PropTypes.string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add prop in alphabetical order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't know about this, done :)
src/addons/Portal/Portal.js
Outdated
@@ -126,6 +129,7 @@ class Portal extends Component { | |||
closeOnDocumentClick: true, | |||
closeOnEscape: true, | |||
openOnTriggerClick: true, | |||
eventPool: 'default', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^
src/addons/Portal/Portal.js
Outdated
@@ -374,6 +378,7 @@ class Portal extends Component { | |||
const { | |||
mountNode = isBrowser ? document.body : null, | |||
prepend, | |||
eventPool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^
src/addons/Portal/Portal.js
Outdated
@@ -394,6 +399,8 @@ class Portal extends Component { | |||
|
|||
debug('unmountPortal()') | |||
|
|||
const { eventPool } = this.props |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New line before this declaration is useless.
Exactly 👍
I will perform style changes tomorrow, if you will not do them before me 😄 I want to hear there @levithomason, too. I think that we can include it to next release on this weekend. |
I've been following this issue/PR and I'm happy with this result 👍. Thanks for hashing it out guys. |
Released in |
Looking at the multiple modals example in the docs for v0.76, a single press of the Escape key closes both modals. I am seeing the same behavior in my project even with unique |
@drewsbrew If that is what you are experiencing, please open up a separate bug report form with a codesandbox example. |
@drewsbrew Bug actually exists, however @brianespinosa please create new issues instead of necroposting. Will be fixed in #2329. |
fixes #2075
Without this change, any event handlers added to EventStack under the 'Portal' namespace will be appended to an array. If another Portal is then mounted, new event handlers will be added to the EventStack and take precedence over the original portal's event handlers.
This change allows each portal to store its event handlers under its own namespace in EventStack, so when you click from one portal to another, the first one is appropriately closed.