Skip to content

Commit 30cee2f

Browse files
authored
Modern Event System: register onMouseEnter for portals (facebook#18720)
1 parent 4e3545f commit 30cee2f

File tree

10 files changed

+63
-0
lines changed

10 files changed

+63
-0
lines changed

packages/react-art/src/ReactARTHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,7 @@ export function beforeActiveInstanceBlur() {
500500
export function afterActiveInstanceBlur() {
501501
// noop
502502
}
503+
504+
export function preparePortalMount(portalInstance: any): void {
505+
// noop
506+
}

packages/react-dom/src/client/ReactDOMHostConfig.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ import {
6464
enableSuspenseServerRenderer,
6565
enableDeprecatedFlareAPI,
6666
enableFundamentalAPI,
67+
enableModernEventSystem,
6768
} from 'shared/ReactFeatureFlags';
6869
import {TOP_BEFORE_BLUR, TOP_AFTER_BLUR} from '../events/DOMTopLevelEventTypes';
70+
import {listenToEvent} from '../events/DOMModernPluginEventSystem';
6971

7072
export type Type = string;
7173
export type Props = {
@@ -1098,3 +1100,9 @@ export function makeOpaqueHydratingObject(
10981100
valueOf: attemptToReadValue,
10991101
};
11001102
}
1103+
1104+
export function preparePortalMount(portalInstance: Instance): void {
1105+
if (enableModernEventSystem) {
1106+
listenToEvent('onMouseEnter', portalInstance);
1107+
}
1108+
}

packages/react-dom/src/events/plugins/__tests__/ModernEnterLeaveEventPlugin-test.internal.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,30 @@ describe('EnterLeaveEventPlugin', () => {
239239

240240
ReactDOM.render(<Parent />, container);
241241
});
242+
243+
it('should work with portals outside of the root', () => {
244+
const divRef = React.createRef();
245+
const onMouseLeave = jest.fn();
246+
247+
function Component() {
248+
return (
249+
<div onMouseLeave={onMouseLeave}>
250+
{ReactDOM.createPortal(<div ref={divRef} />, document.body)}
251+
</div>
252+
);
253+
}
254+
255+
ReactDOM.render(<Component />, container);
256+
257+
// Leave from the portal div
258+
divRef.current.dispatchEvent(
259+
new MouseEvent('mouseout', {
260+
bubbles: true,
261+
cancelable: true,
262+
relatedTarget: document.body,
263+
}),
264+
);
265+
266+
expect(onMouseLeave).toHaveBeenCalledTimes(1);
267+
});
242268
});

packages/react-native-renderer/src/ReactFabricHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,3 +514,7 @@ export function beforeActiveInstanceBlur() {
514514
export function afterActiveInstanceBlur() {
515515
// noop
516516
}
517+
518+
export function preparePortalMount(portalInstance: Instance): void {
519+
// noop
520+
}

packages/react-native-renderer/src/ReactNativeHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,7 @@ export function beforeActiveInstanceBlur() {
562562
export function afterActiveInstanceBlur() {
563563
// noop
564564
}
565+
566+
export function preparePortalMount(portalInstance: Instance): void {
567+
// noop
568+
}

packages/react-noop-renderer/src/createReactNoop.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,10 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
449449
afterActiveInstanceBlur() {
450450
// NO-OP
451451
},
452+
453+
preparePortalMount() {
454+
// NO-OP
455+
},
452456
};
453457

454458
const hostConfig = useMutation

packages/react-reconciler/src/ReactFiberCompleteWork.new.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import {
8282
mountFundamentalComponent,
8383
cloneFundamentalInstance,
8484
shouldUpdateFundamentalComponent,
85+
preparePortalMount,
8586
} from './ReactFiberHostConfig';
8687
import {
8788
getRootHostContainer,
@@ -973,6 +974,9 @@ function completeWork(
973974
case HostPortal:
974975
popHostContainer(workInProgress);
975976
updateHostContainer(workInProgress);
977+
if (current === null) {
978+
preparePortalMount(workInProgress.stateNode.containerInfo);
979+
}
976980
return null;
977981
case ContextProvider:
978982
// Pop provider fiber

packages/react-reconciler/src/ReactFiberCompleteWork.old.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import {
8282
mountFundamentalComponent,
8383
cloneFundamentalInstance,
8484
shouldUpdateFundamentalComponent,
85+
preparePortalMount,
8586
} from './ReactFiberHostConfig';
8687
import {
8788
getRootHostContainer,
@@ -973,6 +974,9 @@ function completeWork(
973974
case HostPortal:
974975
popHostContainer(workInProgress);
975976
updateHostContainer(workInProgress);
977+
if (current === null) {
978+
preparePortalMount(workInProgress.stateNode.containerInfo);
979+
}
976980
return null;
977981
case ContextProvider:
978982
// Pop provider fiber

packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export const makeClientIdInDEV = $$$hostConfig.makeClientIdInDEV;
8383
export const makeServerId = $$$hostConfig.makeServerId;
8484
export const beforeActiveInstanceBlur = $$$hostConfig.beforeActiveInstanceBlur;
8585
export const afterActiveInstanceBlur = $$$hostConfig.afterActiveInstanceBlur;
86+
export const preparePortalMount = $$$hostConfig.preparePortalMount;
8687

8788
// -------------------
8889
// Mutation

packages/react-test-renderer/src/ReactTestHostConfig.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,7 @@ export function beforeActiveInstanceBlur() {
435435
export function afterActiveInstanceBlur() {
436436
// noop
437437
}
438+
439+
export function preparePortalMount(portalInstance: Instance): void {
440+
// noop
441+
}

0 commit comments

Comments
 (0)