-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
[Gradient Tool]: Fix closing of popover when the angle control is clicked #40735
[Gradient Tool]: Fix closing of popover when the angle control is clicked #40735
Conversation
Size Change: -10 B (0%) Total Size: 1.23 MB
ℹ️ View Unchanged
|
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 tested this with Gutenberg.run and the issue is fixed. The changes make sense.
Coincidentally, were #40518 merged it would allow fixing this by removing any focus handling here but so far we're not to looking to backport that one so this is a great fix in the meantime.
@@ -28,12 +28,11 @@ function AngleCircle( { value, onChange, ...props } ) { | |||
|
|||
const changeAngleToPosition = ( event ) => { |
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 just noticed this is the handler for onDragMove
and onDragEnd
(in addition to being called by onDragStart
) so it's executing event.target.focus()
way more than necessary. Perhaps even the old blur()
would work if it were only called from onDragStart
. Not that I'm suggesting that blur()
should be used.
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.
Good point! I didn't notice any performance penalty in my testing, but I suppose we could add a check before calling .focus()
to only do that if the element isn't already focused?
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.
Definitely agree here. I noticed this as well that these events are tied together in a bit weird fashion. I'll land this as is to fix the issue for now, and we need to check how to separate/handle the drag events 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.
Thanks for fixing this up @ntsekouras!
I couldn't find the reason for making the popover close and my guess is that there is someone else listening to that event
I was curious so did a little bit of digging into the Popover component:
In the Popover, the dialog props are expanded to the wrapper element of the Popover here, and the props are retrieved from useDialog here. Within useDialog, the props that contain the blur handlers are retrieved via a call to useFocusOutside here, and in useFocusOutside this is where onBlur
is set.
So, that appears to be how the Popover is set up to watch for blur events within its container. There's a bunch of other handlers in useFocusOutside to cancel the call to the onFocusOutside callback for onFocus
, onMouseDown
, onMouseUp
, etc. The onBlur
callback queues the check via a setTimeout
to give the other handlers a chance to cancel / prevent the blur callback from firing, which appears to be how we get the "focus outside" behaviour.
The approach here to skip blurring the element and instead call .focus()
to intentionally focus the desired element makes sense to me as a way to fix the underlying issue by avoiding blurring from within the Popover.
Perhaps, separately, we might need to add additional logic to the useFocusOutside
hook to also take into account the drag event handlers (e.g. onDragMove
, onDragEnd
, etc) so that they're recognised as valid reasons not to call the focus outside callback.
At any rate, this change tests well, and LGTM!
Thanks for the reviews and also for digging @andrewserong!
That sounds like a plan. |
I cherry picked this change into |
Thank you folks for collaborating on this PR! I didn't get to leave a review, but changes LGTM 🚀 Could we just add a CHANGELOG entry for this bug fix in a follow-up ? |
What?
Fixes: #40661
From the issue:
How?
In this PR there were changes that affected InputControl and how it updates/syncs values. That PR added a line of code in angle circle control to programmatically
blur
the active element.I couldn't find the reason for making the popover close and my guess is that there is someone else listening to that event and/or a rerender somewhere is triggered. I'd love to learn why it was happening if anyone knows or debugs a bit 😄 --cc @ciampo @aaronrobertshaw
What I did here was explicitly focus the current node(angle circle) if clicked, to contain the triggered event with the same effect.
Testing Instructions
Before
After
Screen.Recording.2022-04-29.at.5.07.21.PM.mov