radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.87k stars 823 forks source link

[DropdownMenu] Nested menu does not open until a mouse move is made after the previous animation is finished #923

Open axelhzf opened 3 years ago

axelhzf commented 3 years ago

Bug report

Current Behavior

I have noticed a weird behaviour related to nested menus on a DropdownMenu:

https://user-images.githubusercontent.com/175627/137897406-50fb5004-9eee-4f8f-b4e0-771af18836e2.mp4

It looks like to open the nested menu on the second item, I need to move the mouse after the animation (of the first menu item) has finished. If I don't move the mouse after the animation is finished, the menu won't open.

Expected behavior

I would expect the nested menu to open after the previous animation end

Reproducible example

CodeSandbox Template

Your environment

Software Name(s) Version
Radix Package(s) react-dropdown-menu 0.1.1
React n/a 17.0.2
Browser Chrome 94.0.4606.81
Assistive tech
Node n/a
npm/yarn
Operating System MacOs 11.6
benoitgrelard commented 3 years ago

@axelhzf Thanks for reporting this. I can't get it to do it consistently, I think it may be an issue with our pointer grace logic. We'll take a look!

andy-hook commented 3 years ago

I might be misunderstanding the issue but I don't think this is related to the animation timing. Because we use a timer (300ms) combined with an “intent zone”, the open handler won’t fire on mousemove unless that timer has expired, we leave the zone, or we move in the opposite direction.

In this case the timer has expired but the trigger won’t re-test until the next mousemove event (the trailing motion in the vid) so to me this works per our implementation though it could definitely be improved!

benoitgrelard commented 3 years ago

Yeah I think you're spot on @andy-hook, I've tested without animations and it's reproducible too. We could definitely look at improving this though.

axelhzf commented 3 years ago

You are right, the problem is not related to the animation.

After taking a look at the code I think I understand the problem better:

In a situation like this one

where you have A submenu open. When there is a mouseLeave on the item A, a timer is started to see if the intention is to go to the submenu

while this timer is active, a mouseEnter on the B item will be prevented.

The buggy situation happens when this timer ends. If the mouse is on the 'B' item, inside the green area, the item won't be active until a mouseMove event happens.

I think a solution could be to activate the item when the timer ends. I give it a try here https://github.com/axelhzf/primitives/commit/eb46adda8723ad36bdfb4da9426415dad0910584

But I didn't find a good way to active the item properly :( https://github.com/axelhzf/primitives/commit/eb46adda8723ad36bdfb4da9426415dad0910584#diff-2c017addf9d983e22f2792c45966b54177b23ca8eae7ec303bec0324245a80a9R548

benoitgrelard commented 2 years ago

This would likely require polling cursor position and figuring out what is underneath as no pointer event would be raised, so we're unlikely to fix this.

benoitgrelard commented 2 years ago

We're unlikely to fix this, but we'll keep it open as it's a fair suggestion.

MaxMusing commented 2 months ago

2372 is somewhat related but more apparent since it isn't resolved after a mouseMove event, only after the cursor fully leaves the grace area.

https://github.com/user-attachments/assets/41214917-255d-49ad-9f5c-cc2d65431c59

ashishbairwa commented 1 month ago

Agree with @MaxMusing , it's still happening. @benoitgrelard possible to give a workaround for this.