@@ -4,12 +4,9 @@ import {
4
4
useControlledState ,
5
5
useGetLatest ,
6
6
generateBoundingClientRect ,
7
- isMouseOutside ,
8
7
} from './utils' ;
9
8
import { Config , PopperOptions , PropsGetterArgs , TriggerType } from './types' ;
10
9
11
- const { isArray } = Array ;
12
-
13
10
const virtualElement = {
14
11
getBoundingClientRect : generateBoundingClientRect ( ) ,
15
12
} ;
@@ -51,7 +48,7 @@ export function usePopperTooltip(
51
48
const defaultModifiers = React . useMemo (
52
49
( ) => [ { name : 'offset' , options : { offset : finalConfig . offset } } ] ,
53
50
// eslint-disable-next-line react-hooks/exhaustive-deps
54
- isArray ( finalConfig . offset ) ? finalConfig . offset : [ ]
51
+ Array . isArray ( finalConfig . offset ) ? finalConfig . offset : [ ]
55
52
) ;
56
53
57
54
const finalPopperOptions = {
@@ -69,7 +66,7 @@ export function usePopperTooltip(
69
66
} ) ;
70
67
71
68
const timer = React . useRef < number > ( ) ;
72
- React . useEffect ( ( ) => ( ) => clearTimeout ( timer . current ) ) ;
69
+ React . useEffect ( ( ) => ( ) => clearTimeout ( timer . current ) , [ ] ) ;
73
70
74
71
const { styles, attributes, ...popperProps } = usePopper (
75
72
finalConfig . followCursor ? virtualElement : triggerRef ,
@@ -88,12 +85,14 @@ export function usePopperTooltip(
88
85
89
86
const isTriggeredBy = React . useCallback (
90
87
( trigger : TriggerType ) => {
91
- return isArray ( finalConfig . trigger )
88
+ return Array . isArray ( finalConfig . trigger )
92
89
? finalConfig . trigger . includes ( trigger )
93
90
: finalConfig . trigger === trigger ;
94
91
} ,
95
92
// eslint-disable-next-line react-hooks/exhaustive-deps
96
- isArray ( finalConfig . trigger ) ? finalConfig . trigger : [ finalConfig . trigger ]
93
+ Array . isArray ( finalConfig . trigger )
94
+ ? finalConfig . trigger
95
+ : [ finalConfig . trigger ]
97
96
) ;
98
97
99
98
const hideTooltip = React . useCallback ( ( ) => {
@@ -184,64 +183,12 @@ export function usePopperTooltip(
184
183
if ( triggerRef == null || ! isTriggeredBy ( 'hover' ) ) return ;
185
184
186
185
triggerRef . addEventListener ( 'mouseenter' , showTooltip ) ;
187
- let stopTimer : undefined | ( ( ) => void ) ;
188
- if ( ! visible ) {
189
- stopTimer = ( ) => clearTimeout ( timer . current ) ;
190
- triggerRef . addEventListener ( 'mouseleave' , stopTimer ) ;
191
- }
186
+ triggerRef . addEventListener ( 'mouseleave' , hideTooltip ) ;
192
187
return ( ) => {
193
188
triggerRef . removeEventListener ( 'mouseenter' , showTooltip ) ;
194
- if ( stopTimer ) {
195
- triggerRef . removeEventListener ( 'mouseleave' , stopTimer ) ;
196
- }
197
- } ;
198
- } , [ isTriggeredBy , hideTooltip , showTooltip , triggerRef , visible ] ) ;
199
- // Listen for mouse exiting the hover area &&
200
- // handle the followCursor
201
- React . useEffect ( ( ) => {
202
- if (
203
- ! visible ||
204
- triggerRef == null ||
205
- ( ! isTriggeredBy ( 'hover' ) && ! finalConfig . followCursor )
206
- ) {
207
- return ;
208
- }
209
-
210
- let lastMouseOutside = false ;
211
- const handleMouseMove = ( event : MouseEvent ) => {
212
- const mouseOutside = isMouseOutside (
213
- event ,
214
- triggerRef ,
215
- ! finalConfig . followCursor &&
216
- getLatest ( ) . finalConfig . interactive &&
217
- tooltipRef
218
- ) ;
219
- if ( mouseOutside && lastMouseOutside !== mouseOutside ) {
220
- hideTooltip ( ) ;
221
- }
222
- if ( ! mouseOutside && finalConfig . followCursor ) {
223
- virtualElement . getBoundingClientRect = generateBoundingClientRect (
224
- event . clientX ,
225
- event . clientY
226
- ) ;
227
- update ?.( ) ;
228
- }
229
- lastMouseOutside = mouseOutside ;
189
+ triggerRef . removeEventListener ( 'mouseleave' , hideTooltip ) ;
230
190
} ;
231
- window . addEventListener ( 'mousemove' , handleMouseMove ) ;
232
- return ( ) => {
233
- window . removeEventListener ( 'mousemove' , handleMouseMove ) ;
234
- } ;
235
- } , [
236
- finalConfig . followCursor ,
237
- getLatest ,
238
- hideTooltip ,
239
- isTriggeredBy ,
240
- tooltipRef ,
241
- triggerRef ,
242
- update ,
243
- visible ,
244
- ] ) ;
191
+ } , [ triggerRef , isTriggeredBy , showTooltip , hideTooltip ] ) ;
245
192
246
193
// Trigger: hover on tooltip, keep it open if hovered
247
194
React . useEffect ( ( ) => {
@@ -262,6 +209,28 @@ export function usePopperTooltip(
262
209
if ( finalConfig . closeOnTriggerHidden && isReferenceHidden ) hideTooltip ( ) ;
263
210
} , [ finalConfig . closeOnTriggerHidden , hideTooltip , isReferenceHidden ] ) ;
264
211
212
+ // Handle follow cursor
213
+ React . useEffect ( ( ) => {
214
+ if ( ! finalConfig . followCursor || triggerRef == null ) return ;
215
+
216
+ function setMousePosition ( {
217
+ clientX,
218
+ clientY,
219
+ } : {
220
+ clientX : number ;
221
+ clientY : number ;
222
+ } ) {
223
+ virtualElement . getBoundingClientRect = generateBoundingClientRect (
224
+ clientX ,
225
+ clientY
226
+ ) ;
227
+ update ?.( ) ;
228
+ }
229
+
230
+ triggerRef . addEventListener ( 'mousemove' , setMousePosition ) ;
231
+ return ( ) => triggerRef . removeEventListener ( 'mousemove' , setMousePosition ) ;
232
+ } , [ finalConfig . followCursor , triggerRef , update ] ) ;
233
+
265
234
// Handle tooltip DOM mutation changes (aka mutation observer)
266
235
React . useEffect ( ( ) => {
267
236
if (
@@ -285,6 +254,7 @@ export function usePopperTooltip(
285
254
...styles . popper ,
286
255
} ,
287
256
...attributes . popper ,
257
+ 'data-popper-interactive' : finalConfig . interactive ,
288
258
} ;
289
259
} ;
290
260
0 commit comments