@@ -23,7 +23,8 @@ const Tooltip = ({
2323 delayShow = 0 ,
2424 delayHide = 0 ,
2525 float = false ,
26- noArrow,
26+ noArrow = false ,
27+ clickable = false ,
2728 style : externalStyles ,
2829 position,
2930 // props handled by controller
@@ -43,6 +44,7 @@ const Tooltip = ({
4344 const lastFloatPosition = useRef < IPosition | null > ( null )
4445 const { anchorRefs, setActiveAnchor : setProviderActiveAnchor } = useTooltip ( ) ( id )
4546 const [ activeAnchor , setActiveAnchor ] = useState < React . RefObject < HTMLElement > > ( { current : null } )
47+ const hoveringTooltip = useRef ( false )
4648
4749 const handleShow = ( value : boolean ) => {
4850 if ( setIsOpen ) {
@@ -62,14 +64,17 @@ const Tooltip = ({
6264 } , delayShow )
6365 }
6466
65- const handleHideTooltipDelayed = ( ) => {
67+ const handleHideTooltipDelayed = ( delay = delayHide ) => {
6668 if ( tooltipHideDelayTimerRef . current ) {
6769 clearTimeout ( tooltipHideDelayTimerRef . current )
6870 }
6971
7072 tooltipHideDelayTimerRef . current = setTimeout ( ( ) => {
73+ if ( hoveringTooltip . current ) {
74+ return
75+ }
7176 handleShow ( false )
72- } , delayHide )
77+ } , delay )
7378 }
7479
7580 const handleShowTooltip = ( event ?: Event ) => {
@@ -93,7 +98,10 @@ const Tooltip = ({
9398 }
9499
95100 const handleHideTooltip = ( ) => {
96- if ( delayHide ) {
101+ if ( clickable ) {
102+ // allow time for the mouse to reach the tooltip, in case there's a gap
103+ handleHideTooltipDelayed ( delayHide || 50 )
104+ } else if ( delayHide ) {
97105 handleHideTooltipDelayed ( )
98106 } else {
99107 handleShow ( false )
@@ -207,6 +215,19 @@ const Tooltip = ({
207215 }
208216 }
209217
218+ const handleMouseEnterTooltip = ( ) => {
219+ hoveringTooltip . current = true
220+ }
221+ const handleMouseLeaveTooltip = ( ) => {
222+ hoveringTooltip . current = false
223+ handleHideTooltip ( )
224+ }
225+
226+ if ( clickable ) {
227+ tooltipRef . current ?. addEventListener ( 'mouseenter' , handleMouseEnterTooltip )
228+ tooltipRef . current ?. addEventListener ( 'mouseleave' , handleMouseLeaveTooltip )
229+ }
230+
210231 enabledEvents . forEach ( ( { event, listener } ) => {
211232 elementRefs . forEach ( ( ref ) => {
212233 ref . current ?. addEventListener ( event , listener )
@@ -215,6 +236,10 @@ const Tooltip = ({
215236
216237 return ( ) => {
217238 window . removeEventListener ( 'click' , handleClickOutsideAnchor )
239+ if ( clickable ) {
240+ tooltipRef . current ?. removeEventListener ( 'mouseenter' , handleMouseEnterTooltip )
241+ tooltipRef . current ?. removeEventListener ( 'mouseleave' , handleMouseLeaveTooltip )
242+ }
218243 enabledEvents . forEach ( ( { event, listener } ) => {
219244 elementRefs . forEach ( ( ref ) => {
220245 ref . current ?. removeEventListener ( event , listener )
@@ -297,6 +322,7 @@ const Tooltip = ({
297322 className = { classNames ( 'react-tooltip' , styles [ 'tooltip' ] , styles [ variant ] , className , {
298323 [ styles [ 'show' ] ] : hasContentOrChildren && ! calculatingPosition && ( isOpen || show ) ,
299324 [ styles [ 'fixed' ] ] : positionStrategy === 'fixed' ,
325+ [ styles [ 'clickable' ] ] : clickable ,
300326 } ) }
301327 style = { { ...externalStyles , ...inlineStyles } }
302328 ref = { tooltipRef }
0 commit comments