-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
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
[Select] Dispatch click event with same target of the mousedown event #25630
Conversation
@material-ui/core: parsed: +0.11% , gzip: +0.09% |
@@ -116,6 +116,7 @@ describe('<Select />', () => { | |||
const trigger = getByRole('button'); | |||
|
|||
fireEvent.mouseDown(trigger); | |||
fireEvent.click(trigger); |
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.
I had to add this click to every fireEvent.mouseDown
so that the previous added event listener is removed.
Added the "on hold" label as I want to use the e2e job to test this use case. |
d6569a0
to
36b249b
Compare
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.
I have updated the issue description to link #18655 that will likely come up again with the changes here. No objections to giving this approach a try. I would personally favor the change in the ClickAwayListener logic I had initially proposed. It would be more resilient, It's not too hard to trigger the same issue: https://codesandbox.io/s/simplepopper-material-demo-forked-1xw2n?file=/demo.tsx.
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.
Fixing the behavior for the clickAwayListener is important. We can't also dispatch synthetic events. We would now compete with the browser and React. Adding new, unspecified behavior. But not only is the behavior unspecified, it actually violates existing specification (click events should be dispatched on the common ancestor of mousedown/mouseup).
I talked with the React folks who faced this very issue recently and will share their recommendations this week. Dispatching synthetic events was not among the considered approaches.
@@ -116,6 +116,7 @@ describe('<Select />', () => { | |||
const trigger = getByRole('button'); | |||
|
|||
fireEvent.mouseDown(trigger); | |||
fireEvent.click(trigger); |
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.
This is one indicator that this change is problematic. What happens if there is no click registered on the trigger due to interactions with other elements?
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.
There's no problem if the click occurs in other element, here it could even be in the document.body
. I just need to issue it to clear the previous added listener or it will cause unexpected behavior in the next fireEvent.mouseDown
below.
doc.removeEventListener('click', handleClick.current, true); | ||
} | ||
|
||
// Since the targets of the `mousedown` and `mouseup` events are different, |
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.
It's not clear at this point in the code that this is the case. Wouldn't you want to check that during mouseup?
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.
To check during mouseup
I would have to add another listener to the document and from this listener add another one to cancel and re-dispatch the click
.
|
||
// Since the targets of the `mousedown` and `mouseup` events are different, | ||
// the browser will dispatch the `click` to a common ancestor. | ||
// This stops the next `click` and re-dispatch it with the right target. |
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.
Why do you think the specified behavior is not the "right" target?
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.
Because it's not clear that, because a transparent div is placed in the mousedown
, the target of mouseup
changes.
@eps1lon Even if we discard this PR to avoid dispatching new events, there's still the problem that the click doesn't propagate. It's not intuitive for users writing unit-tests to have to use the mousedown to click the select. #18655 #19250 |
Hello 👋 , I happened to stumble upon this PR after debugging what I think is a similar issue, in my case, I am trying to track the user's click event on the Select field, and I am doing this through heap analytics, although once a user clicks on select, heap recognizes the event on Is this related to the current issue? If not could you point me how to fix this? Thank you in advance 🤗 |
@aditya2337 Yes, this PR is related to your issue. The click event is not dispatched in the Select field but in the body or other common ancestor. The |
Ah, awesome 👏 thank you!! |
I changed the approach here. Instead of dispatching new events, I'm setting |
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.
The new approach makes me think of #23466. Looks better
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.
Let's discuss this on the next planning meeting. There are some misunderstandings that we should sync on. Mostly onboarding issues.
I'm closing as the effort has been stale for a while. |
Closes #25578
Trade-offs:
click
events in the capture phasefireEvent.mouseDown
must also callfireEvent.click
to clear the added listener. Related to [Select] No longer listens to click events #18655A codesandbox with the upstream issue and the fix in this PR: https://codesandbox.io/s/datagrid-bug-demo-forked-ntsb3?file=/package.json