Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[menu-button] Menu in dialog can be opened only after the second click with React v17 #808

Closed
akirilchik opened this issue Jun 11, 2021 · 7 comments
Labels
Status: Investigation Type: Bug Something isn't working

Comments

@akirilchik
Copy link

馃悰 Bug report

Hi guys, please take a look. Thanks in advance.

Menu in dialog can be opened only after the second click with React v17.

Current Behavior

Menu in dialog can be opened only after the second click with React v17.

Screen.Recording.2021-06-11.at.15.39.03.mov

Expected behavior

Menu in dialog should be opened after the first click.

Reproducible example

CodeSandbox Template

Your environment

Software Name(s) Version
Reach Package latest
React latest (17)
Browser Chrome latest
Assistive tech
Node
npm/yarn
Operating System MacOs Big Sur 11.4
@akirilchik
Copy link
Author

Any news?

@chaance
Copy link
Member

chaance commented Jun 29, 2021

I haven't had a chance to look into this yet, but it's on my list for the next release.

@chaance chaance added Type: Bug Something isn't working Status: Investigation labels Jun 29, 2021
@chaance
Copy link
Member

chaance commented Jul 10, 2021

Looks like it's fighting with react-focus-lock a bit, triggering a blur event that immediately reverts the menu button's state after the initial click. I'll need to investigate this further in the dependency.

@austsinovich
Copy link

How is this investigation? Any updates?

@chaance
Copy link
Member

chaance commented Jul 26, 2021

Found the problem, haven't had time to implement/test the solution. Menu popovers are portaled, so when they receive focus the focus-lock kicks in and immediately steals it back, which triggers the menu popover blur event and closes it before you ever see anything.

react-focus-lock has a few techniques for handling portaled elements. If this is a priority for you, I'd happily take a PR if you have time to go down this rabbit hole before I do! https://github.com/theKashey/react-focus-lock#portals

chaance added a commit that referenced this issue Jul 31, 2021
Portaled menus still will not work correctly, but if this is needed
users can pass portal={false} to `MenuList` to prevent conflicts with
the dialog's focus lock. These changes make it easier to deal with
non-portaled popovers by allowing consumers to render the `Menu`
component as a DOM node that can be relatively positioned.

This change also removes the outdated `data-reach-menu` attribute from
the popover and uses it for the wrapping menu *if* a DOM node is
rendered. This is a breaking change.
@chaance
Copy link
Member

chaance commented Jul 31, 2021

Alright, so I spent some more time on this tonight and here's the deal.

With react-focus-lock there are features that make handling focus with nested portaled elements possible, but it would be quite tricky for us to integrate in a way that "just works" by default. This would require some additional work to come up with the right API, and frankly I just don't have enough time to dedicate to new features/APIs at the moment. Hopefully that changes in the future, but here we are 馃槃

That said, here's my response + a solution:

  • We can't currently support portaled popovers inside of dialog without major changes
  • To nest MenuButton inside of dialog and prevent the double-click issue:
    • Set portal prop to false on either MenuList or MenuItems depending on the API you're using
    • Wrap Menu in a relative-positioned DOM element so that the popover is positioned correctly relative to the button

I've made changes for the next release that will allow Menu to accept an as prop to make the second step a little easier, but you can wrap it in your own DOM element just as well. I added an example inside-dialog.example.tsx that shows this working on the current dev branch, and I'll update the docs to make this our official solution.

@danielstreit
Copy link

I'm hitting this too. Just to connect the dots a bit, I believe the underlying issue is explored here in react-focus-lock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Investigation Type: Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants