From 6c4ef547085f220136da64fc3f8df17e07decc7e Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 26 Jan 2024 08:42:02 -0800 Subject: [PATCH] BridgelessUIManager: Finish findSubviewIn Summary: This is an implementation of UIManagerModule.findSubviewIn, based on the [Fabric renderer](https://github.com/facebook/react-fbsource-import/blob/772935f7320f37a14ef06a9616dd43fa090d54a3/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js#L28899-L28953). UIManager.findSubviewIn(viewTag, point, callback) The point is relative to viewTag's parent's (0, 0). Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D52642884 fbshipit-source-id: 775e98d23ff42d41c30644b82f5f67e788df4ee6 --- .../ReactNative/BridgelessUIManager.js | 49 ++++++++++++++++++- .../Libraries/ReactNative/FabricUIManager.js | 6 +++ .../ReactNative/__mocks__/FabricUIManager.js | 9 ++++ .../__snapshots__/public-api-test.js.snap | 6 +++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js index 832ff1caf39..4a004b5ec29 100644 --- a/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js +++ b/packages/react-native/Libraries/ReactNative/BridgelessUIManager.js @@ -336,7 +336,54 @@ const UIManagerJS: UIManagerJSInterface & {[string]: any} = { height: number, ) => void, ): void => { - raiseSoftError('findSubviewIn'); + if (reactTag == null) { + console.error( + `findSubviewIn() noop: Cannot be called with ${String( + reactTag, + )} reactTag`, + ); + return; + } + + const FabricUIManager = nullthrows(getFabricUIManager()); + const shadowNode = FabricUIManager.findShadowNodeByTag_DEPRECATED(reactTag); + + if (!shadowNode) { + console.error( + `findSubviewIn() noop: Cannot find view with reactTag ${reactTag}`, + ); + return; + } + + FabricUIManager.findNodeAtPoint( + shadowNode, + point[0], + point[1], + function (internalInstanceHandle) { + if (internalInstanceHandle == null) { + console.error('findSubviewIn(): Cannot find node at point'); + return; + } + + let instanceHandle: Object = internalInstanceHandle; + let node = instanceHandle.stateNode.node; + + if (!node) { + console.error('findSubviewIn(): Cannot find node at point'); + return; + } + + let nativeViewTag = (instanceHandle.stateNode.canonical + .nativeTag: number); + + FabricUIManager.measure( + node, + function (x, y, width, height, pageX, pageY) { + callback(nativeViewTag, pageX, pageY, width, height); + }, + ); + }, + ); }, viewIsDescendantOf: ( reactTag: ?number, diff --git a/packages/react-native/Libraries/ReactNative/FabricUIManager.js b/packages/react-native/Libraries/ReactNative/FabricUIManager.js index 99c8c438d49..8233a12f3fe 100644 --- a/packages/react-native/Libraries/ReactNative/FabricUIManager.js +++ b/packages/react-native/Libraries/ReactNative/FabricUIManager.js @@ -64,6 +64,12 @@ export interface Spec { commandName: string, args: Array, ) => void; + +findNodeAtPoint: ( + node: Node, + locationX: number, + locationY: number, + callback: (instanceHandle: ?InternalInstanceHandle) => void, + ) => void; /** * Support methods for the DOM-compatible APIs. diff --git a/packages/react-native/Libraries/ReactNative/__mocks__/FabricUIManager.js b/packages/react-native/Libraries/ReactNative/__mocks__/FabricUIManager.js index b2a8c545b35..c51df7240c1 100644 --- a/packages/react-native/Libraries/ReactNative/__mocks__/FabricUIManager.js +++ b/packages/react-native/Libraries/ReactNative/__mocks__/FabricUIManager.js @@ -292,6 +292,15 @@ const FabricUIManagerMock: IFabricUIManagerMock = { findShadowNodeByTag_DEPRECATED: jest.fn((reactTag: number): ?Node => {}), + findNodeAtPoint: jest.fn( + ( + node: Node, + locationX: number, + locationY: number, + callback: (instanceHandle: ?InternalInstanceHandle) => void, + ): void => {}, + ), + getBoundingClientRect: jest.fn( ( node: Node, diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 99104b4063c..7f7729af0e9 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -6564,6 +6564,12 @@ export interface Spec { commandName: string, args: Array ) => void; + +findNodeAtPoint: ( + node: Node, + locationX: number, + locationY: number, + callback: (instanceHandle: ?InternalInstanceHandle) => void + ) => void; +getParentNode: (node: Node) => ?InternalInstanceHandle; +getChildNodes: (node: Node) => $ReadOnlyArray; +isConnected: (node: Node) => boolean;