Modern Event System: register onMouseEnter for portals (#18720)

This commit is contained in:
Dominic Gannaway
2020-04-23 20:57:52 +01:00
committed by GitHub
parent 4e3545fd6f
commit 30cee2f4c7
10 changed files with 63 additions and 0 deletions
+4
View File
@@ -500,3 +500,7 @@ export function beforeActiveInstanceBlur() {
export function afterActiveInstanceBlur() {
// noop
}
export function preparePortalMount(portalInstance: any): void {
// noop
}
+8
View File
@@ -64,8 +64,10 @@ import {
enableSuspenseServerRenderer,
enableDeprecatedFlareAPI,
enableFundamentalAPI,
enableModernEventSystem,
} from 'shared/ReactFeatureFlags';
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
import {listenToEvent} from '../events/DOMModernPluginEventSystem';
export type Type = string;
export type Props = {
@@ -1098,3 +1100,9 @@ export function makeOpaqueHydratingObject(
valueOf: attemptToReadValue,
};
}
export function preparePortalMount(portalInstance: Instance): void {
if (enableModernEventSystem) {
listenToEvent('onMouseEnter', portalInstance);
}
}
@@ -239,4 +239,30 @@ describe('EnterLeaveEventPlugin', () => {
ReactDOM.render(<Parent />, container);
});
it('should work with portals outside of the root', () => {
const divRef = React.createRef();
const onMouseLeave = jest.fn();
function Component() {
return (
<div onMouseLeave={onMouseLeave}>
{ReactDOM.createPortal(<div ref={divRef} />, document.body)}
</div>
);
}
ReactDOM.render(<Component />, container);
// Leave from the portal div
divRef.current.dispatchEvent(
new MouseEvent('mouseout', {
bubbles: true,
cancelable: true,
relatedTarget: document.body,
}),
);
expect(onMouseLeave).toHaveBeenCalledTimes(1);
});
});
@@ -514,3 +514,7 @@ export function beforeActiveInstanceBlur() {
export function afterActiveInstanceBlur() {
// noop
}
export function preparePortalMount(portalInstance: Instance): void {
// noop
}
@@ -562,3 +562,7 @@ export function beforeActiveInstanceBlur() {
export function afterActiveInstanceBlur() {
// noop
}
export function preparePortalMount(portalInstance: Instance): void {
// noop
}
+4
View File
@@ -449,6 +449,10 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
afterActiveInstanceBlur() {
// NO-OP
},
preparePortalMount() {
// NO-OP
},
};
const hostConfig = useMutation
@@ -82,6 +82,7 @@ import {
mountFundamentalComponent,
cloneFundamentalInstance,
shouldUpdateFundamentalComponent,
preparePortalMount,
} from './ReactFiberHostConfig';
import {
getRootHostContainer,
@@ -973,6 +974,9 @@ function completeWork(
case HostPortal:
popHostContainer(workInProgress);
updateHostContainer(workInProgress);
if (current === null) {
preparePortalMount(workInProgress.stateNode.containerInfo);
}
return null;
case ContextProvider:
// Pop provider fiber
@@ -82,6 +82,7 @@ import {
mountFundamentalComponent,
cloneFundamentalInstance,
shouldUpdateFundamentalComponent,
preparePortalMount,
} from './ReactFiberHostConfig';
import {
getRootHostContainer,
@@ -973,6 +974,9 @@ function completeWork(
case HostPortal:
popHostContainer(workInProgress);
updateHostContainer(workInProgress);
if (current === null) {
preparePortalMount(workInProgress.stateNode.containerInfo);
}
return null;
case ContextProvider:
// Pop provider fiber
@@ -83,6 +83,7 @@ export const makeClientIdInDEV = $$$hostConfig.makeClientIdInDEV;
export const makeServerId = $$$hostConfig.makeServerId;
export const beforeActiveInstanceBlur = $$$hostConfig.beforeActiveInstanceBlur;
export const afterActiveInstanceBlur = $$$hostConfig.afterActiveInstanceBlur;
export const preparePortalMount = $$$hostConfig.preparePortalMount;
// -------------------
// Mutation
@@ -435,3 +435,7 @@ export function beforeActiveInstanceBlur() {
export function afterActiveInstanceBlur() {
// noop
}
export function preparePortalMount(portalInstance: Instance): void {
// noop
}