hoverEnd does not fire on button move/resize under cursor
See original GitHub issue🐛 Bug Report
If a user clicks a button and the button resizes or moves position on the page so that it is no longer under the cursor, the onHoverEnd event does not fire and isHovered remains true.
Steps to reproduce:
- Make button with react-aria’s
useButtonanduseHover - Create effect that reacts to isHovered and isPressed and moves/resizes the button onPress so it is no longer under the cursor
- Notice that onHoverEnd did not fire and isHovered is still true.
Code sandbox link: https://codesandbox.io/s/hoverendnotfiring-25h7dh?file=/src/App.js
🤔 Expected Behavior
The isHovered variable should become false and onHoverEnd should be fired.
😯 Current Behavior
hoverEnd event does not fire and isHovered remains true!
Here is code sandbox link: https://codesandbox.io/s/hoverendnotfiring-25h7dh?file=/src/App.js
💁 Possible Solution
I think adding a delayed check to see if the button is still under cursor after onPressEnd will fix this problem. Or, we can work on making an all-in-one hook/solution for buttons that want hover effects. Right now, it feels a little weird to have useButton to also need useHover.
🔦 Context
Being inspired by Sam Selikoff’s video, How to build an Animated Button with React Aria and Framer Motion, I set out to make my own “perfect” button with hover states.
In the image above, the buttons circles are the problematic buttons that move/change shape on click, creating this issue of retaining their hover states.
💻 Code Sample
https://codesandbox.io/s/hoverendnotfiring-25h7dh?file=/src/App.js
🌍 Your Environment
| Software | Version(s) |
|---|---|
| react-aria | 3.19.0 |
| Browser | Tested on Chromium, Firefox, and Safari and behavior is same |
| Operating System | MacOS |
This issue does not happen on mobile because there are no hovers on mobile (normally, lol).
I also use Framer motion to fix the active state not appearing, but that has no effect on this issue as I have a button in the code sandbox without framer-motion experiencing the same issue.
Issue Analytics
- State:
- Created a year ago
- Comments:7 (4 by maintainers)

Top Related StackOverflow Question
Tested a few browsers, seems pretty inconsistent: https://codepen.io/devongovett/pen/PoeKmwB
:hoverstate immediately when the button moves (on click).:hoverimmediately on click, fires onpointerleave after moving the mouse by at least 1px.:hoverand fires onpointerleave after moving the mouse.But since onpointerleave does eventually get fired in all browsers, it should work.
But that button isn’t working, it still shows hovered as true. Also, if you hover it a second time, the state is stale and it won’t trigger an on hover.
This is something we’d need to build into useHover. I’m just not sure the best way to do that without incurring performance hits like I mentioned.
I’ll respond back here after I’ve had a chance to discuss it with the team.