Skip to content

Commit ee76107

Browse files
rubennortefacebook-github-bot
authored andcommitted
Bring ReactFabricHostComponent back to react-native (#36570)
Summary: Pull Request resolved: #36570 I'm doing some preparations to implement this proposal to bring some DOM APIs to React Native refs: react-native-community/discussions-and-proposals#607 To make it easier to iterate on the proposal, and to improve the separation of concerns between React and React Native, I'm moving the definition of `ReactFabricHostComponent` (the public instance provided by React when using refs on host conmponents) to the `react-native` package. I already did some steps in the React repository to simplify this: * Removing unused imperative events that caused increased coupling: facebook/react#26282 * Extracting the definition of the public instance to a separate module: facebook/react#26291 In this case, in order to be able to move the definition from React to React Native, we need to: 1. Create the definition in React Native and export it through `ReactNativePrivateInterface`. 2. Update React to use that definition instead of the one in its own module. This diff implements the first step. `ReactNativeAttributePayload` is required by this definition and by the one for Paper that still exists in React. I moved it here so we only define it where we use it when we remove Paper. Paper will access it through `ReactNativePrivateInterface` as well. That will also allow us to remove a few other fields in that interface. Changelog: [Internal] bypass-github-export-checks Reviewed By: yungsters Differential Revision: D43772356 fbshipit-source-id: 78dac152f415f19316ec90887127bf9861fe3110
1 parent 64ea075 commit ee76107

File tree

7 files changed

+1127
-8
lines changed

7 files changed

+1127
-8
lines changed

jest.config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ module.exports = {
2828
testPathIgnorePatterns: [
2929
'/node_modules/',
3030
'<rootDir>/packages/react-native/template',
31-
'<rootDir>/packages/react-native/Libraries/Renderer',
31+
'<rootDir>/packages/react-native/Libraries/Renderer/implementations',
32+
'<rootDir>/packages/react-native/Libraries/Renderer/shims',
3233
'<rootDir>/packages/rn-tester/e2e',
3334
],
3435
transformIgnorePatterns: ['node_modules/(?!@react-native/)'],

packages/react-native/Libraries/ReactNative/FabricUIManager.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,13 @@ import type {
1515
MeasureInWindowOnSuccessCallback,
1616
MeasureLayoutOnSuccessCallback,
1717
MeasureOnSuccessCallback,
18+
Node,
1819
} from '../Renderer/shims/ReactNativeTypes';
1920
import type {RootTag} from '../Types/RootTagTypes';
2021

21-
// TODO: type these properly.
22-
export opaque type Node = {...};
23-
type NodeSet = Array<Node>;
24-
type NodeProps = {...};
25-
type InstanceHandle = {...};
22+
export type NodeSet = Array<Node>;
23+
export type NodeProps = {...};
24+
export type InstanceHandle = {...};
2625
export type Spec = {|
2726
+createNode: (
2827
reactTag: number,
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
import type {
13+
LayoutAnimationConfig,
14+
MeasureInWindowOnSuccessCallback,
15+
MeasureLayoutOnSuccessCallback,
16+
MeasureOnSuccessCallback,
17+
Node,
18+
} from '../../Renderer/shims/ReactNativeTypes';
19+
import type {RootTag} from '../../Types/RootTagTypes';
20+
import type {
21+
InstanceHandle,
22+
NodeProps,
23+
NodeSet,
24+
Spec as FabricUIManager,
25+
} from '../FabricUIManager';
26+
27+
type NodeMock = {
28+
reactTag: number,
29+
rootTag: RootTag,
30+
props: NodeProps,
31+
instanceHandle: InstanceHandle,
32+
children: NodeSet,
33+
};
34+
35+
function fromNode(node: Node): NodeMock {
36+
// $FlowExpectedError[incompatible-return]
37+
return node;
38+
}
39+
40+
function toNode(node: NodeMock): Node {
41+
// $FlowExpectedError[incompatible-return]
42+
return node;
43+
}
44+
45+
const FabricUIManagerMock: FabricUIManager = {
46+
createNode: jest.fn(
47+
(
48+
reactTag: number,
49+
viewName: string,
50+
rootTag: RootTag,
51+
props: NodeProps,
52+
instanceHandle: InstanceHandle,
53+
): Node => {
54+
return toNode({
55+
reactTag,
56+
rootTag,
57+
props,
58+
instanceHandle,
59+
children: [],
60+
});
61+
},
62+
),
63+
cloneNode: jest.fn((node: Node): Node => {
64+
return toNode({...fromNode(node)});
65+
}),
66+
cloneNodeWithNewChildren: jest.fn((node: Node): Node => {
67+
return toNode({...fromNode(node), children: []});
68+
}),
69+
cloneNodeWithNewProps: jest.fn((node: Node, newProps: NodeProps): Node => {
70+
return toNode({...fromNode(node), props: newProps});
71+
}),
72+
cloneNodeWithNewChildrenAndProps: jest.fn(
73+
(node: Node, newProps: NodeProps): Node => {
74+
return toNode({...fromNode(node), children: [], props: newProps});
75+
},
76+
),
77+
createChildSet: jest.fn((rootTag: RootTag): NodeSet => {
78+
return [];
79+
}),
80+
appendChild: jest.fn((parentNode: Node, child: Node): Node => {
81+
return toNode({
82+
...fromNode(parentNode),
83+
children: fromNode(parentNode).children.concat(child),
84+
});
85+
}),
86+
appendChildToSet: jest.fn((childSet: NodeSet, child: Node): void => {
87+
childSet.push(child);
88+
}),
89+
completeRoot: jest.fn((rootTag: RootTag, childSet: NodeSet): void => {}),
90+
measure: jest.fn((node: Node, callback: MeasureOnSuccessCallback): void => {
91+
callback(10, 10, 100, 100, 0, 0);
92+
}),
93+
measureInWindow: jest.fn(
94+
(node: Node, callback: MeasureInWindowOnSuccessCallback): void => {
95+
callback(10, 10, 100, 100);
96+
},
97+
),
98+
measureLayout: jest.fn(
99+
(
100+
node: Node,
101+
relativeNode: Node,
102+
onFail: () => void,
103+
onSuccess: MeasureLayoutOnSuccessCallback,
104+
): void => {
105+
onSuccess(1, 1, 100, 100);
106+
},
107+
),
108+
configureNextLayoutAnimation: jest.fn(
109+
(
110+
config: LayoutAnimationConfig,
111+
callback: () => void, // check what is returned here
112+
errorCallback: () => void,
113+
): void => {},
114+
),
115+
sendAccessibilityEvent: jest.fn((node: Node, eventType: string): void => {}),
116+
findShadowNodeByTag_DEPRECATED: jest.fn((reactTag: number): ?Node => {}),
117+
getBoundingClientRect: jest.fn(
118+
(
119+
node: Node,
120+
): [
121+
/* x:*/ number,
122+
/* y:*/ number,
123+
/* width:*/ number,
124+
/* height:*/ number,
125+
] => {
126+
return [1, 1, 100, 100];
127+
},
128+
),
129+
setNativeProps: jest.fn((node: Node, newProps: NodeProps): void => {}),
130+
dispatchCommand: jest.fn(
131+
(node: Node, commandName: string, args: Array<mixed>): void => {},
132+
),
133+
};
134+
135+
global.nativeFabricUIManager = FabricUIManagerMock;
136+
137+
export function getFabricUIManager(): ?FabricUIManager {
138+
return FabricUIManagerMock;
139+
}

packages/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,22 @@ import typeof ReactFiberErrorDialog from '../Core/ReactFiberErrorDialog';
1717
import typeof RCTEventEmitter from '../EventEmitter/RCTEventEmitter';
1818
import typeof CustomEvent from '../Events/CustomEvent';
1919
import typeof UIManager from '../ReactNative/UIManager';
20+
import typeof {
21+
createPublicInstance,
22+
getNativeTagFromPublicInstance,
23+
getNodeFromPublicInstance,
24+
} from '../Renderer/public/ReactFabricPublicInstance';
25+
import typeof {
26+
create as createAttributePayload,
27+
diff as diffAttributePayloads,
28+
} from '../Renderer/public/ReactNativeAttributePayload';
2029
import typeof ReactNativeViewConfigRegistry from '../Renderer/shims/ReactNativeViewConfigRegistry';
2130
import typeof flattenStyle from '../StyleSheet/flattenStyle';
31+
import type {DangerouslyImpreciseStyleProp} from '../StyleSheet/StyleSheet';
2232
import typeof deepFreezeAndThrowOnMutationInDev from '../Utilities/deepFreezeAndThrowOnMutationInDev';
2333
import typeof deepDiffer from '../Utilities/differ/deepDiffer';
2434
import typeof Platform from '../Utilities/Platform';
2535

26-
import {type DangerouslyImpreciseStyleProp} from '../StyleSheet/StyleSheet';
27-
2836
// flowlint unsafe-getters-setters:off
2937
module.exports = {
3038
get BatchedBridge(): BatchedBridge {
@@ -48,6 +56,7 @@ module.exports = {
4856
get UIManager(): UIManager {
4957
return require('../ReactNative/UIManager');
5058
},
59+
// TODO: Remove when React has migrated to `createAttributePayload` and `diffAttributePayloads`
5160
get deepDiffer(): deepDiffer {
5261
return require('../Utilities/differ/deepDiffer');
5362
},
@@ -56,6 +65,7 @@ module.exports = {
5665
> {
5766
return require('../Utilities/deepFreezeAndThrowOnMutationInDev');
5867
},
68+
// TODO: Remove when React has migrated to `createAttributePayload` and `diffAttributePayloads`
5969
get flattenStyle(): flattenStyle<DangerouslyImpreciseStyleProp> {
6070
// $FlowFixMe[underconstrained-implicit-instantiation]
6171
return require('../StyleSheet/flattenStyle');
@@ -72,4 +82,22 @@ module.exports = {
7282
get CustomEvent(): CustomEvent {
7383
return require('../Events/CustomEvent').default;
7484
},
85+
get createAttributePayload(): createAttributePayload {
86+
return require('../Renderer/public/ReactNativeAttributePayload').create;
87+
},
88+
get diffAttributePayloads(): diffAttributePayloads {
89+
return require('../Renderer/public/ReactNativeAttributePayload').diff;
90+
},
91+
get createPublicInstance(): createPublicInstance {
92+
return require('../Renderer/public/ReactFabricPublicInstance')
93+
.createPublicInstance;
94+
},
95+
get getNativeTagFromPublicInstance(): getNativeTagFromPublicInstance {
96+
return require('../Renderer/public/ReactFabricPublicInstance')
97+
.getNativeTagFromPublicInstance;
98+
},
99+
get getNodeFromPublicInstance(): getNodeFromPublicInstance {
100+
return require('../Renderer/public/ReactFabricPublicInstance')
101+
.getNodeFromPublicInstance;
102+
},
75103
};

0 commit comments

Comments
 (0)