import getComponentName from '../element/componentName'; import type { ReactElementFiber } from '../element/types'; const EventHandlerNames = [ 'onClick', 'onResponderGrant', 'onResponderMove', 'onResponderRelease', 'onResponderTerminate', 'onResponderTerminationRequest', 'onStartShouldSetResponder', ]; const InternalSet = new Set([ 'TouchableOpacity', 'TouchableHighlight', 'TouchableWithoutFeedback', 'TouchableNativeFeedback', 'Pressable', 'TouchableBounce', ]); function findInternalNode( node: ReactElementFiber | undefined ): ReactElementFiber | undefined { if (!node) { return undefined; } if (!node.elementType) { return findInternalNode(node.return); } const displayName = node.elementType.displayName; if (InternalSet.has(displayName)) { return node; } return findInternalNode(node.return); } function findForward( node: ReactElementFiber | undefined ): ReactElementFiber | undefined { if (!node) { return undefined; } const child = node.child; if (!child) { return findForward(node.return); } const childName = getComponentName(child.elementType); if (childName === 'RCTView') { return findForward(node.return); } /* 其他根据 View 组件上的 eventHanlders 来判定是否可点击 */ if ( EventHandlerNames.every((name) => child.memoizedProps.hasOwnProperty(name)) ) { return node; } return findForward(node.return); } export function findTouchableNode( viewNode: ReactElementFiber ): ReactElementFiber | undefined { const node = findForward(viewNode); if (node) { const internalNode = findInternalNode(node); return internalNode || node; } return undefined; }