react-use icon indicating copy to clipboard operation
react-use copied to clipboard

feat: Add stopPropagation and event access support to useHover hook

Open Cherryga opened this issue 5 months ago โ€ข 0 comments

๐ŸŽฏ Fixes Issue

Resolves streamich/react-use#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.

Cherryga avatar Jul 21 '25 17:07 Cherryga