feat: Add stopPropagation and event access support to useHover hook #2643
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
🎯 Fixes Issue
Resolves #2481
📋 Problem
I encountered a use case where I have multiple nested hoverable elements, and hovering over a child element triggers the hover on the parent as well due to event bubbling. I also needed access to the actual mouse events for more advanced hover interactions.
🔧 Solution
I've enhanced the useHover hook with optional configuration options that solve both issues while maintaining 100% backward compatibility.
1. stopPropagation Option
Prevents hover events from bubbling to parent elements:
jsx
const [childHoverable] = useHover(
(hovered) =>
{ stopPropagation: true }
);
2. Event Access
Provides access to mouse events for advanced use cases:
jsx
const [hoverable] = useHover(
(hovered) =>
{
onMouseEnter: (event) => console.log('Mouse at:', event.clientX, event.clientY),
onMouseLeave: (event) => console.log('Mouse left')
}
);
3. Combined Usage
You can use both options together:
jsx
const [element] = useHover(
(hovered) =>
{
stopPropagation: true,
onMouseEnter: (event) => trackHoverStart(event),
onMouseLeave: (event) => trackHoverEnd(event)
}
);
✅ Features
📁 Files Changed
🧪 Testing
I've added comprehensive test coverage:
📝 Type Definition
typescript
interface UseHoverOptions {
/** Prevents hover events from bubbling to parent elements /
stopPropagation?: boolean;
/* Callback when mouse enters - provides access to mouse event /
onMouseEnter?: (event: React.MouseEvent) => void;
/* Callback when mouse leaves - provides access to mouse event */
onMouseLeave?: (event: React.MouseEvent) => void;
}
const useHover = (
element: Element,
options?: UseHoverOptions
): [React.ReactElement, boolean]
This enhancement makes useHover much more powerful for complex interactive UIs while maintaining the simplicity that makes react-use great.