diff --git a/packages/react-events/src/Hover.js b/packages/react-events/src/Hover.js index 8cb78b77517bc..f8585fae8cdb3 100644 --- a/packages/react-events/src/Hover.js +++ b/packages/react-events/src/Hover.js @@ -29,19 +29,19 @@ if (typeof window !== 'undefined' && window.PointerEvent === undefined) { targetEventTypes.push('touchstart', 'mouseover', 'mouseout'); } -function dispatchHoverInEvents( +function dispatchHoverStartEvents( context: EventResponderContext, props: Object, state: HoverState, ): void { const {event, eventTarget} = context; + if (context.isTargetWithinEventComponent((event: any).relatedTarget)) { + return; + } + if (props.onHoverStart) { + context.dispatchEvent('hoverstart', props.onHoverStart, eventTarget, true); + } if (props.onHoverChange) { - if (context.isTargetWithinEventComponent((event: any).relatedTarget)) { - return; - } - if (props.onHoverIn) { - context.dispatchEvent('hoverin', props.onHoverIn, eventTarget, true); - } const hoverChangeEventListener = () => { props.onHoverChange(true); }; @@ -54,13 +54,13 @@ function dispatchHoverInEvents( } } -function dispatchHoverOutEvents(context: EventResponderContext, props: Object) { +function dispatchHoverEndEvents(context: EventResponderContext, props: Object) { const {event, eventTarget} = context; if (context.isTargetWithinEventComponent((event: any).relatedTarget)) { return; } - if (props.onHoverOut) { - context.dispatchEvent('hoverout', props.onHoverOut, eventTarget, true); + if (props.onHoverEnd) { + context.dispatchEvent('hoverend', props.onHoverEnd, eventTarget, true); } if (props.onHoverChange) { const hoverChangeEventListener = () => { @@ -118,7 +118,7 @@ const HoverResponder = { state.isInHitSlop = true; return; } - dispatchHoverInEvents(context, props, state); + dispatchHoverStartEvents(context, props, state); state.isHovered = true; } break; @@ -126,7 +126,7 @@ const HoverResponder = { case 'pointerout': case 'mouseout': { if (state.isHovered && !state.isTouched) { - dispatchHoverOutEvents(context, props); + dispatchHoverEndEvents(context, props); state.isHovered = false; } state.isInHitSlop = false; @@ -142,7 +142,7 @@ const HoverResponder = { (event: any).y, ) ) { - dispatchHoverInEvents(context, props, state); + dispatchHoverStartEvents(context, props, state); state.isHovered = true; state.isInHitSlop = false; } @@ -153,7 +153,7 @@ const HoverResponder = { (event: any).y, ) ) { - dispatchHoverOutEvents(context, props); + dispatchHoverEndEvents(context, props); state.isHovered = false; state.isInHitSlop = true; } @@ -162,7 +162,7 @@ const HoverResponder = { } case 'pointercancel': { if (state.isHovered && !state.isTouched) { - dispatchHoverOutEvents(context, props); + dispatchHoverEndEvents(context, props); state.isHovered = false; state.isTouched = false; } diff --git a/packages/react-events/src/__tests__/Hover-test.internal.js b/packages/react-events/src/__tests__/Hover-test.internal.js new file mode 100644 index 0000000000000..1250a49917ab3 --- /dev/null +++ b/packages/react-events/src/__tests__/Hover-test.internal.js @@ -0,0 +1,102 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @emails react-core + */ + +'use strict'; + +let React; +let ReactFeatureFlags; +let ReactDOM; +let Hover; + +describe('Hover event responder', () => { + let container; + + beforeEach(() => { + jest.resetModules(); + ReactFeatureFlags = require('shared/ReactFeatureFlags'); + ReactFeatureFlags.enableEventAPI = true; + React = require('react'); + ReactDOM = require('react-dom'); + Hover = require('react-events/hover'); + + container = document.createElement('div'); + document.body.appendChild(container); + }); + + afterEach(() => { + document.body.removeChild(container); + container = null; + }); + + it('should support onHover', () => { + let divRef = React.createRef(); + let events = []; + + function handleOnHover(e) { + if (e) { + events.push('hover in'); + } else { + events.push('hover out'); + } + } + + function Component() { + return ( + +
Hover me!
+
+ ); + } + + ReactDOM.render(, container); + + const mouseOverEvent = document.createEvent('Event'); + mouseOverEvent.initEvent('mouseover', true, true); + divRef.current.dispatchEvent(mouseOverEvent); + + const mouseOutEvent = document.createEvent('Event'); + mouseOutEvent.initEvent('mouseout', true, true); + divRef.current.dispatchEvent(mouseOutEvent); + + expect(events).toEqual(['hover in', 'hover out']); + }); + + it('should support onHoverStart and onHoverEnd', () => { + let divRef = React.createRef(); + let events = []; + + function handleOnHoverStart() { + events.push('onHoverStart'); + } + + function handleOnHoverEnd() { + events.push('onHoverEnd'); + } + + function Component() { + return ( + +
Hover me!
+
+ ); + } + + ReactDOM.render(, container); + + const mouseOverEvent = document.createEvent('Event'); + mouseOverEvent.initEvent('mouseover', true, true); + divRef.current.dispatchEvent(mouseOverEvent); + + const mouseOutEvent = document.createEvent('Event'); + mouseOutEvent.initEvent('mouseout', true, true); + divRef.current.dispatchEvent(mouseOutEvent); + + expect(events).toEqual(['onHoverStart', 'onHoverEnd']); + }); +});