10
10
import type { EventResponderContext } from 'events/EventTypes' ;
11
11
import { REACT_EVENT_COMPONENT_TYPE } from 'shared/ReactSymbols' ;
12
12
13
- const targetEventTypes = [
14
- 'pointerover' ,
15
- 'pointermove' ,
16
- 'pointerout' ,
17
- 'pointercancel' ,
18
- ] ;
13
+ type HoverProps = {
14
+ disabled : boolean ,
15
+ delayHoverEnd : number ,
16
+ delayHoverStart : number ,
17
+ onHoverChange : boolean => void ,
18
+ onHoverEnd : ( e : HoverEvent ) => void ,
19
+ onHoverStart : ( e : HoverEvent ) => void ,
20
+ } ;
19
21
20
22
type HoverState = {
21
23
isHovered : boolean ,
@@ -31,6 +33,21 @@ type HoverEvent = {|
31
33
type : HoverEventType ,
32
34
| } ;
33
35
36
+ // const DEFAULT_HOVER_END_DELAY_MS = 0;
37
+ // const DEFAULT_HOVER_START_DELAY_MS = 0;
38
+
39
+ const targetEventTypes = [
40
+ 'pointerover' ,
41
+ 'pointermove' ,
42
+ 'pointerout' ,
43
+ 'pointercancel' ,
44
+ ] ;
45
+
46
+ // If PointerEvents is not supported (e.g., Safari), also listen to touch and mouse events.
47
+ if ( typeof window !== 'undefined' && window . PointerEvent === undefined ) {
48
+ targetEventTypes . push ( 'touchstart' , 'mouseover' , 'mouseout' ) ;
49
+ }
50
+
34
51
function createHoverEvent (
35
52
type : HoverEventType ,
36
53
target : Element | Document ,
@@ -43,16 +60,9 @@ function createHoverEvent(
43
60
} ;
44
61
}
45
62
46
- // In the case we don't have PointerEvents (Safari), we listen to touch events
47
- // too
48
- if ( typeof window !== 'undefined' && window . PointerEvent === undefined ) {
49
- targetEventTypes . push ( 'touchstart' , 'mouseover' , 'mouseout' ) ;
50
- }
51
-
52
63
function dispatchHoverStartEvents (
53
64
context : EventResponderContext ,
54
- props : Object ,
55
- state : HoverState ,
65
+ props : HoverProps ,
56
66
) : void {
57
67
const { event, eventTarget} = context ;
58
68
if ( context . isTargetWithinEventComponent ( ( event : any ) . relatedTarget ) ) {
@@ -67,19 +77,22 @@ function dispatchHoverStartEvents(
67
77
context . dispatchEvent ( syntheticEvent , { discrete : true } ) ;
68
78
}
69
79
if ( props . onHoverChange ) {
70
- const hoverChangeEventListener = ( ) => {
80
+ const listener = ( ) => {
71
81
props . onHoverChange ( true ) ;
72
82
} ;
73
83
const syntheticEvent = createHoverEvent (
74
84
'hoverchange' ,
75
85
eventTarget ,
76
- hoverChangeEventListener ,
86
+ listener ,
77
87
) ;
78
88
context . dispatchEvent ( syntheticEvent , { discrete : true } ) ;
79
89
}
80
90
}
81
91
82
- function dispatchHoverEndEvents ( context : EventResponderContext , props : Object ) {
92
+ function dispatchHoverEndEvents (
93
+ context : EventResponderContext ,
94
+ props : HoverProps ,
95
+ ) {
83
96
const { event, eventTarget} = context ;
84
97
if ( context . isTargetWithinEventComponent ( ( event : any ) . relatedTarget ) ) {
85
98
return ;
@@ -93,13 +106,13 @@ function dispatchHoverEndEvents(context: EventResponderContext, props: Object) {
93
106
context . dispatchEvent ( syntheticEvent , { discrete : true } ) ;
94
107
}
95
108
if ( props . onHoverChange ) {
96
- const hoverChangeEventListener = ( ) => {
109
+ const listener = ( ) => {
97
110
props . onHoverChange ( false ) ;
98
111
} ;
99
112
const syntheticEvent = createHoverEvent (
100
113
'hoverchange' ,
101
114
eventTarget ,
102
- hoverChangeEventListener ,
115
+ listener ,
103
116
) ;
104
117
context . dispatchEvent ( syntheticEvent , { discrete : true } ) ;
105
118
}
@@ -116,18 +129,22 @@ const HoverResponder = {
116
129
} ,
117
130
handleEvent (
118
131
context : EventResponderContext ,
119
- props : Object ,
132
+ props : HoverProps ,
120
133
state : HoverState ,
121
134
) : void {
122
135
const { eventType, eventTarget, event} = context ;
123
136
124
137
switch ( eventType ) {
125
- case 'touchstart' :
126
- // Touch devices don't have hover support
138
+ /**
139
+ * Prevent hover events when touch is being used.
140
+ */
141
+ case 'touchstart' : {
127
142
if ( ! state . isTouched ) {
128
143
state . isTouched = true ;
129
144
}
130
145
break ;
146
+ }
147
+
131
148
case 'pointerover' :
132
149
case 'mouseover' : {
133
150
if (
@@ -148,7 +165,7 @@ const HoverResponder = {
148
165
state . isInHitSlop = true ;
149
166
return ;
150
167
}
151
- dispatchHoverStartEvents ( context , props , state ) ;
168
+ dispatchHoverStartEvents ( context , props ) ;
152
169
state . isHovered = true ;
153
170
}
154
171
break ;
@@ -172,7 +189,7 @@ const HoverResponder = {
172
189
( event : any ) . y ,
173
190
)
174
191
) {
175
- dispatchHoverStartEvents ( context , props , state ) ;
192
+ dispatchHoverStartEvents ( context , props ) ;
176
193
state . isHovered = true ;
177
194
state . isInHitSlop = false ;
178
195
}
0 commit comments