@samitouri / QOS-React-2 / commits / 2534c0c924

[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 });