[Flare] Add event position properties to Hover responder (#15819)
Dominic Gannaway committed
Jun 4, 2019 at 18:10 UTC
2534c0c924d9258b55b730f3ec5f54814beab12d
2 files changed
+143
-2
packages/react-events/src/Hover.js
+36
-2
@@ -43,6 +43,14 @@ type HoverEvent = {|
43
target: Element | Document,
44
type: HoverEventType,
45
timeStamp: number,
46
+ clientX: null | number,
47
+ clientY: null | number,
48
+ pageX: null | number,
49
+ pageY: null | number,
50
+ screenX: null | number,
51
+ screenY: null | number,
52
+ x: null | number,
53
+ y: null | number,
54
|};
55
56
const DEFAULT_HOVER_END_DELAY_MS = 0;
@@ -61,18 +69,40 @@ if (typeof window !== 'undefined' && window.PointerEvent === undefined) {
69
}
70
71
function createHoverEvent(
72
+ event: ?ReactResponderEvent,
73
context: ReactResponderContext,
74
type: HoverEventType,
75
target: Element | Document,
76
): HoverEvent {
77
+ let clientX = null;
78
+ let clientY = null;
79
+ let pageX = null;
80
+ let pageY = null;
81
+ let screenX = null;
82
+ let screenY = null;
83
+
84
+ if (event) {
85
+ const nativeEvent = (event.nativeEvent: any);
86
+ ({clientX, clientY, pageX, pageY, screenX, screenY} = nativeEvent);
87
+ }
88
+
89
return {
90
target,
91
type,
92
timeStamp: context.getTimeStamp(),
93
+ clientX,
94
+ clientY,
95
+ pageX,
96
+ pageY,
97
+ screenX,
98
+ screenY,
99
+ x: clientX,
100
+ y: clientY,
101
};
102
}
103
104
function dispatchHoverChangeEvent(
105
+ event: null | ReactResponderEvent,
106
context: ReactResponderContext,
107
props: HoverProps,
108
state: HoverState,
@@ -82,6 +112,7 @@ function dispatchHoverChangeEvent(
112
props.onHoverChange(bool);
113
};
114
const syntheticEvent = createHoverEvent(
115
+ event,
116
context,
117
'hoverchange',
118
((state.hoverTarget: any): Element | Document),
@@ -119,6 +150,7 @@ function dispatchHoverStartEvents(
150
151
if (props.onHoverStart) {
152
const syntheticEvent = createHoverEvent(
153
+ event,
154
context,
155
'hoverstart',
156
((target: any): Element | Document),
@@ -126,7 +158,7 @@ function dispatchHoverStartEvents(
158
context.dispatchEvent(syntheticEvent, props.onHoverStart, true);
159
}
160
if (props.onHoverChange) {
129
- dispatchHoverChangeEvent(context, props, state);
161
+ dispatchHoverChangeEvent(event, context, props, state);
162
}
163
};
164
@@ -177,6 +209,7 @@ function dispatchHoverEndEvents(
209
210
if (props.onHoverEnd) {
211
const syntheticEvent = createHoverEvent(
212
+ event,
213
context,
214
'hoverend',
215
((target: any): Element | Document),
@@ -184,7 +217,7 @@ function dispatchHoverEndEvents(
217
context.dispatchEvent(syntheticEvent, props.onHoverEnd, true);
218
}
219
if (props.onHoverChange) {
187
- dispatchHoverChangeEvent(context, props, state);
220
+ dispatchHoverChangeEvent(event, context, props, state);
221
}
222
223
state.isOverTouchHitTarget = false;
@@ -316,6 +349,7 @@ const HoverResponder = {
349
} else {
350
if (props.onHoverMove && state.hoverTarget !== null) {
351
const syntheticEvent = createHoverEvent(
352
+ event,
353
context,
354
'hovermove',
355
state.hoverTarget,
packages/react-events/src/__tests__/Hover-test.internal.js
+107
@@ -464,4 +464,111 @@ describe('Hover event responder', () => {
464
it('expect displayName to show up for event component', () => {
465
expect(Hover.displayName).toBe('Hover');
466
});
467
+
468
+ it('should correctly pass through event properties', () => {
469
+ const timeStamps = [];
470
+ const ref = React.createRef();
471
+ const eventLog = [];
472
+ const logEvent = event => {
473
+ const propertiesWeCareAbout = {
474
+ pageX: event.pageX,
475
+ pageY: event.pageY,
476
+ screenX: event.screenX,
477
+ screenY: event.screenY,
478
+ clientX: event.clientX,
479
+ clientY: event.clientY,
480
+ pointerType: event.pointerType,
481
+ target: event.target,
482
+ timeStamp: event.timeStamp,
483
+ type: event.type,
484
+ };
485
+ timeStamps.push(event.timeStamp);
486
+ eventLog.push(propertiesWeCareAbout);
487
+ };
488
+ const element = (
489
+ <Hover
490
+ onHoverStart={logEvent}
491
+ onHoverEnd={logEvent}
492
+ onHoverMove={logEvent}>
493
+ <button ref={ref} />
494
+ </Hover>
495
+ );
496
+ ReactDOM.render(element, container);
497
+
498
+ ref.current.getBoundingClientRect = () => ({
499
+ top: 10,
500
+ left: 10,
501
+ bottom: 20,
502
+ right: 20,
503
+ });
504
+
505
+ ref.current.dispatchEvent(
506
+ createPointerEvent('pointerover', {
507
+ pointerType: 'mouse',
508
+ pageX: 15,
509
+ pageY: 16,
510
+ screenX: 20,
511
+ screenY: 21,
512
+ clientX: 30,
513
+ clientY: 31,
514
+ }),
515
+ );
516
+ ref.current.dispatchEvent(
517
+ createPointerEvent('pointermove', {
518
+ pointerType: 'mouse',
519
+ pageX: 16,
520
+ pageY: 17,
521
+ screenX: 21,
522
+ screenY: 22,
523
+ clientX: 31,
524
+ clientY: 32,
525
+ }),
526
+ );
527
+ ref.current.dispatchEvent(
528
+ createPointerEvent('pointerout', {
529
+ pointerType: 'mouse',
530
+ pageX: 17,
531
+ pageY: 18,
532
+ screenX: 22,
533
+ screenY: 23,
534
+ clientX: 32,
535
+ clientY: 33,
536
+ }),
537
+ );
538
+ expect(eventLog).toEqual([
539
+ {
540
+ pageX: 15,
541
+ pageY: 16,
542
+ screenX: 20,
543
+ screenY: 21,
544
+ clientX: 30,
545
+ clientY: 31,
546
+ target: ref.current,
547
+ timeStamp: timeStamps[0],
548
+ type: 'hoverstart',
549
+ },
550
+ {
551
+ pageX: 16,
552
+ pageY: 17,
553
+ screenX: 21,
554
+ screenY: 22,
555
+ clientX: 31,
556
+ clientY: 32,
557
+ target: ref.current,
558
+ timeStamp: timeStamps[1],
559
+ type: 'hovermove',
560
+ },
561
+ {
562
+ pageX: 17,
563
+ pageY: 18,
564
+ screenX: 22,
565
+ screenY: 23,
566
+ clientX: 32,
567
+ clientY: 33,
568
+ target: ref.current,
569
+ timeStamp: timeStamps[2],
570
+ type: 'hoverend',
571
+ },
572
+ ]);
573
+ });
574
});