From 384c1eda83795c986dcfbf958f45748be1f1a4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Fri, 3 Mar 2023 18:39:19 +0000 Subject: [PATCH] Remove ReactFabricPublicInstance and used definition from ReactNativePrivateInterface --- .../src/ReactFabricHostConfig.js | 10 +- .../src/ReactFabricPublicInstance.js | 153 ----------- .../src/ReactFabricPublicInstanceUtils.js | 36 --- .../src/ReactNativeFiberInspector.js | 6 +- .../src/ReactNativePublicCompat.js | 11 +- .../ReactNativePrivateInterface.js | 11 + .../ReactPrivate/createPublicInstance.js | 21 ++ .../getNativeTagFromPublicInstance.js | 16 ++ .../ReactPrivate/getNodeFromPublicInstance.js | 20 ++ .../__tests__/ReactFabric-test.internal.js | 4 +- .../ReactFabricAndNative-test.internal.js | 2 +- .../ReactFabricHostComponent-test.internal.js | 248 ------------------ scripts/flow/react-native-host-hooks.js | 13 + 13 files changed, 96 insertions(+), 455 deletions(-) delete mode 100644 packages/react-native-renderer/src/ReactFabricPublicInstance.js delete mode 100644 packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js create mode 100644 packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/createPublicInstance.js create mode 100644 packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNativeTagFromPublicInstance.js create mode 100644 packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNodeFromPublicInstance.js delete mode 100644 packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js diff --git a/packages/react-native-renderer/src/ReactFabricHostConfig.js b/packages/react-native-renderer/src/ReactFabricHostConfig.js index c612fd1eb941f..aa2adb457c586 100644 --- a/packages/react-native-renderer/src/ReactFabricHostConfig.js +++ b/packages/react-native-renderer/src/ReactFabricHostConfig.js @@ -8,10 +8,6 @@ */ import type {TouchedViewDataAtPoint, ViewConfig} from './ReactNativeTypes'; -import { - createPublicInstance, - type ReactFabricHostComponent, -} from './ReactFabricPublicInstance'; import {create, diff} from './ReactNativeAttributePayload'; import {dispatchEvent} from './ReactFabricEventEmitter'; import { @@ -23,6 +19,8 @@ import { import { ReactNativeViewConfigRegistry, deepFreezeAndThrowOnMutationInDev, + createPublicInstance, + type PublicInstance as FabricPublicInstance, } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; const { @@ -62,12 +60,12 @@ export type Instance = { // Reference to the React handle (the fiber) internalInstanceHandle: Object, // Exposed through refs. - publicInstance: ReactFabricHostComponent, + publicInstance: PublicInstance, }, }; export type TextInstance = {node: Node, ...}; export type HydratableInstance = Instance | TextInstance; -export type PublicInstance = ReactFabricHostComponent; +export type PublicInstance = FabricPublicInstance; export type Container = number; export type ChildSet = Object; export type HostContext = $ReadOnly<{ diff --git a/packages/react-native-renderer/src/ReactFabricPublicInstance.js b/packages/react-native-renderer/src/ReactFabricPublicInstance.js deleted file mode 100644 index 282e5af7cde1e..0000000000000 --- a/packages/react-native-renderer/src/ReactFabricPublicInstance.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - */ - -import type {ElementRef} from 'react'; -import type { - ViewConfig, - INativeMethods, - HostComponent, - MeasureInWindowOnSuccessCallback, - MeasureLayoutOnSuccessCallback, - MeasureOnSuccessCallback, -} from './ReactNativeTypes'; - -import {TextInputState} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; -import {create} from './ReactNativeAttributePayload'; -import {warnForStyleProps} from './NativeMethodsMixinUtils'; -import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat'; - -const { - measure: fabricMeasure, - measureInWindow: fabricMeasureInWindow, - measureLayout: fabricMeasureLayout, - setNativeProps, - getBoundingClientRect: fabricGetBoundingClientRect, -} = nativeFabricUIManager; - -const noop = () => {}; - -/** - * This is used for refs on host components. - */ -export class ReactFabricHostComponent implements INativeMethods { - // These need to be accessible from `ReactFabricPublicInstanceUtils`. - __nativeTag: number; - __internalInstanceHandle: mixed; - - _viewConfig: ViewConfig; - - constructor( - tag: number, - viewConfig: ViewConfig, - internalInstanceHandle: mixed, - ) { - this.__nativeTag = tag; - this._viewConfig = viewConfig; - this.__internalInstanceHandle = internalInstanceHandle; - } - - blur() { - TextInputState.blurTextInput(this); - } - - focus() { - TextInputState.focusTextInput(this); - } - - measure(callback: MeasureOnSuccessCallback) { - const node = getNodeFromInternalInstanceHandle( - this.__internalInstanceHandle, - ); - if (node != null) { - fabricMeasure(node, callback); - } - } - - measureInWindow(callback: MeasureInWindowOnSuccessCallback) { - const node = getNodeFromInternalInstanceHandle( - this.__internalInstanceHandle, - ); - if (node != null) { - fabricMeasureInWindow(node, callback); - } - } - - measureLayout( - relativeToNativeNode: number | ElementRef>, - onSuccess: MeasureLayoutOnSuccessCallback, - onFail?: () => void /* currently unused */, - ) { - if ( - typeof relativeToNativeNode === 'number' || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - if (__DEV__) { - console.error( - 'Warning: ref.measureLayout must be called with a ref to a native component.', - ); - } - - return; - } - - const toStateNode = getNodeFromInternalInstanceHandle( - this.__internalInstanceHandle, - ); - const fromStateNode = getNodeFromInternalInstanceHandle( - relativeToNativeNode.__internalInstanceHandle, - ); - - if (toStateNode != null && fromStateNode != null) { - fabricMeasureLayout( - toStateNode, - fromStateNode, - onFail != null ? onFail : noop, - onSuccess != null ? onSuccess : noop, - ); - } - } - - unstable_getBoundingClientRect(): DOMRect { - const node = getNodeFromInternalInstanceHandle( - this.__internalInstanceHandle, - ); - if (node != null) { - const rect = fabricGetBoundingClientRect(node); - - if (rect) { - return new DOMRect(rect[0], rect[1], rect[2], rect[3]); - } - } - - // Empty rect if any of the above failed - return new DOMRect(0, 0, 0, 0); - } - - setNativeProps(nativeProps: {...}): void { - if (__DEV__) { - warnForStyleProps(nativeProps, this._viewConfig.validAttributes); - } - const updatePayload = create(nativeProps, this._viewConfig.validAttributes); - - const node = getNodeFromInternalInstanceHandle( - this.__internalInstanceHandle, - ); - if (node != null && updatePayload != null) { - setNativeProps(node, updatePayload); - } - } -} - -export function createPublicInstance( - tag: number, - viewConfig: ViewConfig, - internalInstanceHandle: mixed, -): ReactFabricHostComponent { - return new ReactFabricHostComponent(tag, viewConfig, internalInstanceHandle); -} diff --git a/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js b/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js deleted file mode 100644 index 203f96589fb7f..0000000000000 --- a/packages/react-native-renderer/src/ReactFabricPublicInstanceUtils.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - * - * @flow strict-local - */ - -import type {ReactFabricHostComponent} from './ReactFabricPublicInstance'; -import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat'; - -/** - * IMPORTANT: This module is used in Paper and Fabric. It needs to be defined - * outside of `ReactFabricPublicInstance` because that module requires - * `nativeFabricUIManager` to be defined in the global scope (which does not - * happen in Paper). - */ - -export function getNativeTagFromPublicInstance( - publicInstance: ReactFabricHostComponent, -): number { - return publicInstance.__nativeTag; -} - -export function getNodeFromPublicInstance( - publicInstance: ReactFabricHostComponent, -): mixed { - if (publicInstance.__internalInstanceHandle == null) { - return null; - } - - return getNodeFromInternalInstanceHandle( - publicInstance.__internalInstanceHandle, - ); -} diff --git a/packages/react-native-renderer/src/ReactNativeFiberInspector.js b/packages/react-native-renderer/src/ReactNativeFiberInspector.js index 38a3855ea92a3..d1884c44eafc5 100644 --- a/packages/react-native-renderer/src/ReactNativeFiberInspector.js +++ b/packages/react-native-renderer/src/ReactNativeFiberInspector.js @@ -17,10 +17,12 @@ import { import getComponentNameFromType from 'shared/getComponentNameFromType'; import {HostComponent} from 'react-reconciler/src/ReactWorkTags'; // Module provided by RN: -import {UIManager} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; +import { + UIManager, + getNodeFromPublicInstance, +} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {enableGetInspectorDataForInstanceInProduction} from 'shared/ReactFeatureFlags'; import {getClosestInstanceFromNode} from './ReactNativeComponentTree'; -import {getNodeFromPublicInstance} from './ReactFabricPublicInstanceUtils'; import {getNodeFromInternalInstanceHandle} from './ReactNativePublicCompat'; const emptyObject = {}; diff --git a/packages/react-native-renderer/src/ReactNativePublicCompat.js b/packages/react-native-renderer/src/ReactNativePublicCompat.js index 569397b4e8347..4a8452ad3550f 100644 --- a/packages/react-native-renderer/src/ReactNativePublicCompat.js +++ b/packages/react-native-renderer/src/ReactNativePublicCompat.js @@ -14,6 +14,8 @@ import type {ElementRef, ElementType} from 'react'; import { UIManager, legacySendAccessibilityEvent, + getNodeFromPublicInstance, + getNativeTagFromPublicInstance, } from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import { @@ -23,11 +25,6 @@ import { import ReactSharedInternals from 'shared/ReactSharedInternals'; import getComponentNameFromType from 'shared/getComponentNameFromType'; -import { - getNodeFromPublicInstance, - getNativeTagFromPublicInstance, -} from './ReactFabricPublicInstanceUtils'; - const ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; export function findHostInstance_DEPRECATED( @@ -83,6 +80,7 @@ export function findHostInstance_DEPRECATED( // findHostInstance handles legacy vs. Fabric differences correctly // $FlowFixMe[incompatible-exact] we need to fix the definition of `HostComponent` to use NativeMethods as an interface, not as a type. + // $FlowFixMe[incompatible-return] return hostInstance; } @@ -147,9 +145,8 @@ export function findNodeHandle(componentOrHandle: any): ?number { return hostInstance; } - // $FlowFixMe[prop-missing] For compatibility with legacy renderer instances + // $FlowFixMe[incompatible-type] For compatibility with legacy renderer instances if (hostInstance._nativeTag != null) { - // $FlowFixMe[incompatible-return] return hostInstance._nativeTag; } diff --git a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js index befc3bb617f4f..03b89b3e711f3 100644 --- a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js +++ b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/ReactNativePrivateInterface.js @@ -7,6 +7,8 @@ * @flow strict-local */ +export opaque type PublicInstance = mixed; + module.exports = { get BatchedBridge() { return require('./BatchedBridge.js'); @@ -44,4 +46,13 @@ module.exports = { get RawEventEmitter() { return require('./RawEventEmitter').default; }, + get getNativeTagFromPublicInstance() { + return require('./getNativeTagFromPublicInstance').default; + }, + get getNodeFromPublicInstance() { + return require('./getNodeFromPublicInstance').default; + }, + get createPublicInstance() { + return require('./createPublicInstance').default; + }, }; diff --git a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/createPublicInstance.js b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/createPublicInstance.js new file mode 100644 index 0000000000000..4f16c9d9ff109 --- /dev/null +++ b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/createPublicInstance.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + */ + +import type {PublicInstance} from './ReactNativePrivateInterface'; + +export default function createPublicInstance( + tag: number, + viewConfig: mixed, + internalInstanceHandle: mixed, +): PublicInstance { + return { + __nativeTag: tag, + __internalInstanceHandle: internalInstanceHandle, + }; +} diff --git a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNativeTagFromPublicInstance.js b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNativeTagFromPublicInstance.js new file mode 100644 index 0000000000000..b6862281494c5 --- /dev/null +++ b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNativeTagFromPublicInstance.js @@ -0,0 +1,16 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + */ + +import type {PublicInstance} from './ReactNativePrivateInterface'; + +export default function getNativeTagFromPublicInstance( + publicInstance: PublicInstance, +) { + return publicInstance.__nativeTag; +} diff --git a/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNodeFromPublicInstance.js b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNodeFromPublicInstance.js new file mode 100644 index 0000000000000..b592968462ed4 --- /dev/null +++ b/packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/getNodeFromPublicInstance.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict + */ + +import type {PublicInstance} from './ReactNativePrivateInterface'; + +import {getNodeFromInternalInstanceHandle} from '../../../../ReactNativePublicCompat'; + +export default function getNodeFromPublicInstance( + publicInstance: PublicInstance, +) { + return getNodeFromInternalInstanceHandle( + publicInstance.__internalInstanceHandle, + ); +} diff --git a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js index 72377b7d12cc5..cdc8882a08554 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js @@ -43,9 +43,9 @@ describe('ReactFabric', () => { require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; getNativeTagFromPublicInstance = - require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance; + require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance; getNodeFromPublicInstance = - require('../ReactFabricPublicInstanceUtils').getNodeFromPublicInstance; + require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNodeFromPublicInstance; act = require('internal-test-utils').act; }); diff --git a/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js index fca6d00c72774..4e0fcad9c80c3 100644 --- a/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js +++ b/packages/react-native-renderer/src/__tests__/ReactFabricAndNative-test.internal.js @@ -37,7 +37,7 @@ describe('created with ReactFabric called with ReactNative', () => { require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') .ReactNativeViewConfigRegistry.register; getNativeTagFromPublicInstance = - require('../ReactFabricPublicInstanceUtils').getNativeTagFromPublicInstance; + require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface').getNativeTagFromPublicInstance; }); it('find Fabric instances with the RN renderer', () => { diff --git a/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js b/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js deleted file mode 100644 index ceab02d8497be..0000000000000 --- a/packages/react-native-renderer/src/__tests__/ReactFabricHostComponent-test.internal.js +++ /dev/null @@ -1,248 +0,0 @@ -/** - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * @emails react-core - * @jest-environment node - */ - -'use strict'; - -import * as React from 'react'; - -beforeEach(() => { - jest.resetModules(); - jest.restoreAllMocks(); - - require('react-native/Libraries/ReactPrivate/InitializeNativeFabricUIManager'); -}); - -/** - * Renders a sequence of mock views as dictated by `keyLists`. The `keyLists` - * argument is an array of arrays which determines the number of render passes, - * how many views will be rendered in each pass, and what the keys are for each - * of the views. - * - * If an element in `keyLists` is null, the entire root will be unmounted. - * - * The return value is an array of arrays with the resulting refs from rendering - * each corresponding array of keys. - * - * If the corresponding array of keys is null, the returned element at that - * index will also be null. - */ -async function mockRenderKeys(keyLists) { - const ReactFabric = require('react-native-renderer/fabric'); - const createReactNativeComponentClass = - require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface') - .ReactNativeViewConfigRegistry.register; - const act = require('internal-test-utils').act; - - const mockContainerTag = 11; - const MockView = createReactNativeComponentClass('RCTMockView', () => ({ - validAttributes: {foo: true}, - uiViewClassName: 'RCTMockView', - })); - - const result = []; - for (let i = 0; i < keyLists.length; i++) { - const keyList = keyLists[i]; - if (Array.isArray(keyList)) { - const refs = keyList.map(key => undefined); - await act(() => { - ReactFabric.render( - - {keyList.map((key, index) => ( - { - refs[index] = ref; - }} - /> - ))} - , - mockContainerTag, - ); - }); - // Clone `refs` to ignore future passes. - result.push([...refs]); - continue; - } - if (keyList == null) { - await act(() => { - ReactFabric.stopSurface(mockContainerTag); - }); - result.push(null); - continue; - } - throw new TypeError( - `Invalid 'keyLists' element of type ${typeof keyList}.`, - ); - } - - return result; -} - -describe('blur', () => { - test('blur() invokes TextInputState', async () => { - const { - TextInputState, - } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'); - - const [[fooRef]] = await mockRenderKeys([['foo']]); - - fooRef.blur(); - - expect(TextInputState.blurTextInput.mock.calls).toEqual([[fooRef]]); - }); -}); - -describe('focus', () => { - test('focus() invokes TextInputState', async () => { - const { - TextInputState, - } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'); - - const [[fooRef]] = await mockRenderKeys([['foo']]); - - fooRef.focus(); - - expect(TextInputState.focusTextInput.mock.calls).toEqual([[fooRef]]); - }); -}); - -describe('measure', () => { - test('component.measure(...) invokes callback', async () => { - const [[fooRef]] = await mockRenderKeys([['foo']]); - - const callback = jest.fn(); - fooRef.measure(callback); - - expect(nativeFabricUIManager.measure).toHaveBeenCalledTimes(1); - expect(callback.mock.calls).toEqual([[10, 10, 100, 100, 0, 0]]); - }); - - test('unmounted.measure(...) does nothing', async () => { - const [[fooRef]] = await mockRenderKeys([['foo'], null]); - - const callback = jest.fn(); - fooRef.measure(callback); - - expect(nativeFabricUIManager.measure).not.toHaveBeenCalled(); - expect(callback).not.toHaveBeenCalled(); - }); -}); - -describe('measureInWindow', () => { - test('component.measureInWindow(...) invokes callback', async () => { - const [[fooRef]] = await mockRenderKeys([['foo']]); - - const callback = jest.fn(); - fooRef.measureInWindow(callback); - - expect(nativeFabricUIManager.measureInWindow).toHaveBeenCalledTimes(1); - expect(callback.mock.calls).toEqual([[10, 10, 100, 100]]); - }); - - test('unmounted.measureInWindow(...) does nothing', async () => { - const [[fooRef]] = await mockRenderKeys([['foo'], null]); - - const callback = jest.fn(); - fooRef.measureInWindow(callback); - - expect(nativeFabricUIManager.measureInWindow).not.toHaveBeenCalled(); - expect(callback).not.toHaveBeenCalled(); - }); -}); - -describe('measureLayout', () => { - test('component.measureLayout(component, ...) invokes callback', async () => { - const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar']]); - - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - fooRef.measureLayout(barRef, successCallback, failureCallback); - - expect(nativeFabricUIManager.measureLayout).toHaveBeenCalledTimes(1); - expect(successCallback.mock.calls).toEqual([[1, 1, 100, 100]]); - }); - - test('unmounted.measureLayout(component, ...) does nothing', async () => { - const [[fooRef, barRef]] = await mockRenderKeys([ - ['foo', 'bar'], - ['foo', null], - ]); - - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - fooRef.measureLayout(barRef, successCallback, failureCallback); - - expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled(); - expect(successCallback).not.toHaveBeenCalled(); - }); - - test('component.measureLayout(unmounted, ...) does nothing', async () => { - const [[fooRef, barRef]] = await mockRenderKeys([ - ['foo', 'bar'], - [null, 'bar'], - ]); - - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - fooRef.measureLayout(barRef, successCallback, failureCallback); - - expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled(); - expect(successCallback).not.toHaveBeenCalled(); - }); - - test('unmounted.measureLayout(unmounted, ...) does nothing', async () => { - const [[fooRef, barRef]] = await mockRenderKeys([['foo', 'bar'], null]); - - const successCallback = jest.fn(); - const failureCallback = jest.fn(); - fooRef.measureLayout(barRef, successCallback, failureCallback); - - expect(nativeFabricUIManager.measureLayout).not.toHaveBeenCalled(); - expect(successCallback).not.toHaveBeenCalled(); - }); -}); - -describe('unstable_getBoundingClientRect', () => { - test('component.unstable_getBoundingClientRect() returns DOMRect', async () => { - const [[fooRef]] = await mockRenderKeys([['foo']]); - - const rect = fooRef.unstable_getBoundingClientRect(); - - expect(nativeFabricUIManager.getBoundingClientRect).toHaveBeenCalledTimes( - 1, - ); - expect(rect.toJSON()).toMatchObject({ - x: 10, - y: 10, - width: 100, - height: 100, - }); - }); - - test('unmounted.unstable_getBoundingClientRect() returns empty DOMRect', async () => { - const [[fooRef]] = await mockRenderKeys([['foo'], null]); - - const rect = fooRef.unstable_getBoundingClientRect(); - - expect(nativeFabricUIManager.getBoundingClientRect).not.toHaveBeenCalled(); - expect(rect.toJSON()).toMatchObject({x: 0, y: 0, width: 0, height: 0}); - }); -}); - -describe('setNativeProps', () => { - test('setNativeProps(...) invokes setNativeProps on Fabric UIManager', async () => { - const { - UIManager, - } = require('react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'); - - const [[fooRef]] = await mockRenderKeys([['foo']]); - fooRef.setNativeProps({foo: 'baz'}); - - expect(UIManager.updateView).not.toBeCalled(); - expect(nativeFabricUIManager.setNativeProps).toHaveBeenCalledTimes(1); - }); -}); diff --git a/scripts/flow/react-native-host-hooks.js b/scripts/flow/react-native-host-hooks.js index 7cb3e389126c5..d3f5d3b7b50c5 100644 --- a/scripts/flow/react-native-host-hooks.js +++ b/scripts/flow/react-native-host-hooks.js @@ -16,6 +16,7 @@ type __MeasureInWindowOnSuccessCallback = any; type __MeasureLayoutOnSuccessCallback = any; type __ReactNativeBaseComponentViewConfig = any; type __ViewConfigGetter = any; +type __ViewConfig = any; // libdefs cannot actually import. This is supposed to be the type imported // from 'react-native-renderer/src/legacy-events/TopLevelEventTypes'; @@ -143,6 +144,18 @@ declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface' emit: (channel: string, event: RawEventEmitterEvent) => string, ... }; + declare export opaque type PublicInstance; + declare export function getNodeFromPublicInstance( + publicInstance: PublicInstance, + ): Object; + declare export function getNativeTagFromPublicInstance( + publicInstance: PublicInstance, + ): number; + declare export function createPublicInstance( + tag: number, + viewConfig: __ViewConfig, + internalInstanceHandle: mixed, + ): PublicInstance; } declare module 'react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore' {