From ba0d606ef9a91dd3796c4140f324d223e7ee8c3f Mon Sep 17 00:00:00 2001 From: Shevilll Date: Sat, 20 Jun 2026 15:11:55 +0530 Subject: [PATCH] fix(tooltip): propagate press event object to onPress (#5003) --- src/components/Tooltip/Tooltip.tsx | 27 ++++++++++++++-------- src/components/Tooltip/utils.ts | 9 ++++++-- src/components/__tests__/Tooltip.test.tsx | 28 ++++++++++++++++++++++- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index 36dc08971b..fe451e6a9b 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -6,7 +6,11 @@ import { Platform, Pressable, } from 'react-native'; -import type { LayoutChangeEvent, ViewStyle } from 'react-native'; +import type { + GestureResponderEvent, + LayoutChangeEvent, + ViewStyle, +} from 'react-native'; import { getTooltipPosition } from './utils'; import type { Measurement, TooltipChildProps } from './utils'; @@ -146,15 +150,18 @@ const Tooltip = ({ hideTooltipTimer.current.push(id); }, [leaveTouchDelay]); - const handlePress = React.useCallback(() => { - if (touched.current) { - return null; - } - if (!isValidChild) return null; - const props = children.props as TooltipChildProps; - if (props.disabled) return null; - return props.onPress?.(); - }, [children.props, isValidChild]); + const handlePress = React.useCallback( + (e: GestureResponderEvent) => { + if (touched.current) { + return null; + } + if (!isValidChild) return null; + const props = children.props as TooltipChildProps; + if (props.disabled) return null; + return props.onPress?.(e); + }, + [children.props, isValidChild] + ); const handleHoverIn = React.useCallback(() => { handleTouchStart(); diff --git a/src/components/Tooltip/utils.ts b/src/components/Tooltip/utils.ts index 43baf684fd..304f79d988 100644 --- a/src/components/Tooltip/utils.ts +++ b/src/components/Tooltip/utils.ts @@ -1,5 +1,10 @@ import { Dimensions, StyleSheet } from 'react-native'; -import type { LayoutRectangle, StyleProp, ViewStyle } from 'react-native'; +import type { + GestureResponderEvent, + LayoutRectangle, + StyleProp, + ViewStyle, +} from 'react-native'; type ChildrenMeasurement = { width: number; @@ -19,7 +24,7 @@ export type Measurement = { export type TooltipChildProps = { style: StyleProp; disabled?: boolean; - onPress?: () => void; + onPress?: (e: GestureResponderEvent) => void; onHoverIn?: () => void; onHoverOut?: () => void; }; diff --git a/src/components/__tests__/Tooltip.test.tsx b/src/components/__tests__/Tooltip.test.tsx index 62666e9d7c..397275457a 100644 --- a/src/components/__tests__/Tooltip.test.tsx +++ b/src/components/__tests__/Tooltip.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Dimensions, Text, View, Platform } from 'react-native'; -import type { ViewProps } from 'react-native'; +import type { GestureResponderEvent, ViewProps } from 'react-native'; import { afterAll, @@ -31,6 +31,7 @@ const DummyComponent = ({ ...props }: ViewProps & { ref?: React.RefObject; + onPress?: (e: GestureResponderEvent) => void; }) => ( dummy component @@ -126,6 +127,31 @@ describe('Tooltip', () => { }); }); + describe('press', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('propagates the press event object to the child onPress', () => { + const onPress = jest.fn(); + + const { + wrapper: { getByText }, + } = setup({ + children: , + }); + + const event = { nativeEvent: { locationX: 1, locationY: 2 } }; + + fireEvent(getTrigger(getByText), 'press', event); + + expect(onPress).toHaveBeenCalledTimes(1); + expect(onPress).toHaveBeenCalledWith( + expect.objectContaining({ nativeEvent: event.nativeEvent }) + ); + }); + }); + describe('longPress', () => { beforeAll(() => { jest.spyOn(global, 'clearTimeout');