downshift: Selection via mouse click does not work when menu is inside a portal
downshiftversion: 1.3.0nodeversion:npm(oryarn) version:
What you did:
Trying to implement simple select component using Downshift. The requirement for my select is that menu is inside a portal. I’m using react-portal npm package that leverages React’s native createPortal() API.
What happened:
After I’ve put menu inside portal, selection via mouse stopped working. Menu is being closed as always, but selection does not happen.
Reproduction repository:
Here’s a sandbox: https://codesandbox.io/s/w7p91ol19k
You can try selecting one of menu items. The onChange is not happening, the state is not changed. Try removing Portal element. Without portal everything works as expected.
I believe, there is something to do with mousedown and blur event handlers.
I have found that there are native event listeners for mousedown and mouseup events.
They are preventing the selection of item due to calling reset prior to that.
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 22 (10 by maintainers)
Commits related to this issue
- fix(menu): don't reset downshift if clicking within the menu Closes #287 — committed to downshift-js/downshift by deleted user 6 years ago
- fix(menu): don't reset downshift if clicking within the menu Closes #287 — committed to downshift-js/downshift by deleted user 6 years ago
- feat(2.0.0): release v2! (#461) * feat(2.0.0): squashed commits of everything! fix(TypeScript): Change typings (#373) BREAKING CHANGE: TypeScript typings are much more complete now. fix(expo... — committed to downshift-js/downshift by deleted user 6 years ago
- feat(2.0.0): release v2! (#461) * feat(2.0.0): squashed commits of everything! fix(TypeScript): Change typings (#373) BREAKING CHANGE: TypeScript typings are much more complete now. fix(expo... — committed to Rendez/downshift by deleted user 6 years ago
🎉 This issue has been resolved in version 2.0.0 🎉
The release is available on:
npm package (@latest dist-tag)Your semantic-release bot 📦🚀
I still had the issue (v3.2.10). The solution of @circlingthesun solve it:
Thanks for the report! We could probably add a feature for the upcoming getMenuProps function (see the pull requests) which would apply a ref so we can check that as well as the root ref… Unless someone else has another idea.
lol, I was just working on this and having a really hard time reproducing it. I finally upgraded the original codesandbox to the latest version of downshift and the bug is gone!
However, it’s still possible to reproduce if the user clicks on a non-item that’s rendered within the portal, like here. So I’ll fix that 😃
I’m planning on spending time soon to finish #285 and resolve this among other updates.
If anyone wants that to happen sooner then please feel free to open a PR 😃
@rhinoceraptor thanks. My workaround was to use
onMouseDown={e => selectItem(item)}. That looks less hacky 😃You can avoid that with a well-placed
position: relativeon the container andposition: absoluteon the menu. You shouldn’t need portals for that.I’m so glad!
Hey folks! #285 was merged (into the
nextbranch). Anyone want to work on adding arefKeyprop to the newgetMenuPropsmethod? Make sure you make your branch off thenextbranch!+1 for
getMenuPropsor any solution that would allow use with a Portal. The behavior of the menu pushing all content below it down the page is undesirable in many circumstances. It would be great render the menu in a portal passing in the values fromthis.button.getBoundingClientRect()so the menu can be positioned absolutely below the button without pushing content down.Downshifthas been a total joy to work with so far @kentcdodds. Terrific work and I’m looking forward to the updates.I’m at a cabin with my family right now with very limited internet access, but there is a work around. Any time you don’t like what downshift does with state, you can control it yourself (see the readme). There’s an example you can see here: https://github.com/paypal/downshift/blob/master/stories/examples/controlled.js
It’s not an example of the workarounds necessarily, but hopefully that will point you in the right direction. If someone would like to help out by providing an example in codesandbox or something that’d be great!
I have found: https://github.com/paypal/downshift/blob/master/src/downshift.js#L796-L800
Here there is a check for mouseup event target to be inside the root element. Due to mouseup being browser native event and not a react synthetic one, this condition is met. That’s because the menu is outside of Downshift root element.