Skip to content

Commit

Permalink
fix: Tooltip wasn't showing (callstack#3844)
Browse files Browse the repository at this point in the history
  • Loading branch information
gedu authored and lukewalczak committed Apr 27, 2023
1 parent 3dacabd commit a7cc33e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
21 changes: 15 additions & 6 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
LayoutChangeEvent,
StyleSheet,
Platform,
Pressable,
ViewStyle,
} from 'react-native';

import type { ThemeProp } from 'src/types';
Expand Down Expand Up @@ -149,6 +151,9 @@ const Tooltip = ({
return children.props.onPress?.();
}
}, [children.props]),
onLongPress: () => handleTouchStart(),
onPressOut: () => handleTouchEnd(),
delayLongPress: enterTouchDelay,
};

const webPressProps = {
Expand Down Expand Up @@ -193,17 +198,17 @@ const Tooltip = ({
</View>
</Portal>
)}
<View
onTouchStart={handleTouchStart}
onTouchEnd={handleTouchEnd}
onTouchCancel={handleTouchEnd}
{/* Need the xxPressProps in both places */}
<Pressable
ref={childrenWrapperRef}
style={styles.pressContainer}
{...(isWeb ? webPressProps : mobilePressProps)}
>
{React.cloneElement(children, {
...rest,
ref: childrenWrapperRef,
...(isWeb ? webPressProps : mobilePressProps),
})}
</View>
</Pressable>
</>
);
};
Expand All @@ -222,6 +227,10 @@ const styles = StyleSheet.create({
hidden: {
opacity: 0,
},
pressContainer: {
cursor: 'default',
alignSelf: 'flex-start',
} as ViewStyle,
});

export default Tooltip;
38 changes: 22 additions & 16 deletions src/components/__tests__/Tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('Tooltip', () => {
wrapper: { getByText, unmount },
} = setup({ enterTouchDelay: 5000 });

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

unmount();

Expand All @@ -86,7 +86,7 @@ describe('Tooltip', () => {
wrapper: { getByText, unmount },
} = setup({ enterTouchDelay: 5000 });

fireEvent(getByText('dummy component'), 'touchEnd');
fireEvent(getByText('dummy component'), 'onPressOut');

unmount();

Expand All @@ -98,7 +98,7 @@ describe('Tooltip', () => {
wrapper: { getByText, findByText, unmount },
} = setup();

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

await findByText('some tooltip text');

Expand All @@ -108,7 +108,7 @@ describe('Tooltip', () => {
});
});

describe('touchStart', () => {
describe('onLongPress', () => {
beforeAll(() => jest.spyOn(global, 'clearTimeout'));
afterEach(() => jest.clearAllMocks());

Expand All @@ -119,25 +119,28 @@ describe('Tooltip', () => {
wrapper: { getByText },
} = setup();

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'touchEnd');
fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');
fireEvent(getByText('dummy component'), 'onPressOut');
fireEvent(getByText('dummy component'), 'onLongPress');

expect(global.clearTimeout).toHaveBeenCalledTimes(2);
});
});

describe.each([
['touchEnd', 'hides the tooltip when the user stop pressing the component'],
['touchCancel', 'hides the tooltip when the user cancel the touch action'],
[
'onPressOut',
'hides the tooltip when the user stop pressing the component',
],
['onPressOut', 'hides the tooltip when the user cancel the touch action'],
])('%s', (eventName, testDescription) => {
// eslint-disable-next-line jest/valid-title
it(testDescription, async () => {
const {
wrapper: { queryByText, getByText, findByText },
} = setup({ enterTouchDelay: 50, leaveTouchDelay: 0 });

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

await findByText('some tooltip text');

Expand Down Expand Up @@ -170,7 +173,7 @@ describe('Tooltip', () => {
wrapper: { getByText, getByTestId, findByText },
} = setup();

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

fireEvent(await findByText('some tooltip text'), 'layout', {
nativeEvent: {
Expand All @@ -191,18 +194,21 @@ describe('Tooltip', () => {
describe('When it overflows to left', () => {
it('renders the tooltip with the right placement', async () => {
const {
wrapper: { getByText, getByTestId, findByText },
wrapper: { getByText, findByTestId, findByText },
} = setup({}, { pageX: 0 }); // Component starting at the starting 0 X coord

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

fireEvent(await findByText('some tooltip text'), 'layout', {
nativeEvent: {
layout: { width: TOOLTIP_WIDTH, height: TOOLTIP_HEIGHT },
},
});
const tooltipContainer = await findByTestId('tooltip-container');

expect(getByTestId('tooltip-container').props.style).toMatchObject([
// expect to partial match the style object
expect;
expect(tooltipContainer.props.style).toMatchObject([
{},
{
left: 0, // Tooltip renders starting from children's x coord
Expand All @@ -218,7 +224,7 @@ describe('Tooltip', () => {
wrapper: { getByText, getByTestId, findByText },
} = setup({}, { pageX: 900, width: 150 }); // Component close to the screen limit

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

fireEvent(await findByText('some tooltip text'), 'layout', {
nativeEvent: {
Expand All @@ -242,7 +248,7 @@ describe('Tooltip', () => {
wrapper: { getByText, getByTestId, findByText },
} = setup({}, { pageY: 600, height: 50 });

fireEvent(getByText('dummy component'), 'touchStart');
fireEvent(getByText('dummy component'), 'onLongPress');

fireEvent(await findByText('some tooltip text'), 'layout', {
nativeEvent: {
Expand Down

0 comments on commit a7cc33e

Please sign in to comment.