Skip to content

Conversation

Cherryga
Copy link

🎯 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) =>

Child
,
{ stopPropagation: true }
);

2. Event Access

Provides access to mouse events for advanced use cases:
jsx
const [hoverable] = useHover(
(hovered) =>

Element
,
{
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) =>

Interactive Element
,
{
stopPropagation: true,
onMouseEnter: (event) => trackHoverStart(event),
onMouseLeave: (event) => trackHoverEnd(event)
}
);

✅ Features

  • 100% Backward Compatible - All existing code continues to work unchanged
  • TypeScript Support - Full type safety with UseHoverOptions interface
  • Event Propagation Control - Optional stopPropagation parameter
  • Event Access - onMouseEnter/onMouseLeave callbacks with full event objects
  • Preserves Original Handlers - Existing element handlers are maintained
  • Production Ready - Comprehensive tests, documentation, and examples

📁 Files Changed

  • src/useHover.ts - Enhanced hook implementation with new options
  • src/index.ts - Updated TypeScript exports
  • docs/useHover.md - Updated documentation with usage examples
  • stories/useHover.story.tsx - Added comprehensive demo stories showing nested behavior
  • tests/useHover.test.tsx - Added 17 comprehensive tests covering all scenarios

🧪 Testing

I've added comprehensive test coverage:

  • ✅ Backward compatibility tests (no breaking changes)
  • ✅ stopPropagation functionality tests
  • ✅ Event callback access tests
  • ✅ Combined options tests
  • ✅ Edge case handling tests
  • ✅ All 17 tests pass
  • ✅ TypeScript compilation successful
  • ✅ ESLint passes

📝 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useHover propagation

1 participant