Skip to content

Commit 8744bde

Browse files
authored
fix(tooltips): prevent Tooltip from interfering with a popup (menu, dialog, etc.) trigger (#2023)
1 parent ca92c4b commit 8744bde

File tree

6 files changed

+111
-15
lines changed

6 files changed

+111
-15
lines changed

package-lock.json

Lines changed: 8 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { Meta, Canvas, Story } from '@storybook/addon-docs';
2+
import { Tooltip } from '@zendeskgarden/react-tooltips';
3+
import { MenuStory } from './stories/MenuStory';
4+
5+
<Meta title="Packages/Tooltips/[patterns]" component={Tooltip} />
6+
7+
# Patterns
8+
9+
## Menu
10+
11+
The following example demonstrates `Tooltip` behavior together with a popup
12+
menu. The tooltip is designed to hide when the popup is expanded.
13+
14+
<Canvas>
15+
<Story
16+
name="Menu"
17+
parameters={{ controls: { include: ['appendToNode', 'placement'] } }}
18+
args={{
19+
appendToNode: false,
20+
placement: 'bottom'
21+
}}
22+
argTypes={{
23+
appendToNode: { control: 'boolean' }
24+
}}
25+
>
26+
{args => <MenuStory {...args} />}
27+
</Story>
28+
</Canvas>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright Zendesk, Inc.
3+
*
4+
* Use of this source code is governed under the Apache License, Version 2.0
5+
* found at http://www.apache.org/licenses/LICENSE-2.0.
6+
*/
7+
8+
import React, { forwardRef } from 'react';
9+
import { useTheme } from 'styled-components';
10+
import { StoryFn } from '@storybook/react';
11+
import Icon from '@zendeskgarden/svg-icons/src/16/leaf-stroke.svg';
12+
import { useDocument } from '@zendeskgarden/react-theming';
13+
import { Grid } from '@zendeskgarden/react-grid';
14+
import { Menu, Item, IMenuProps } from '@zendeskgarden/react-dropdowns';
15+
import { ITooltipProps, Tooltip } from '@zendeskgarden/react-tooltips';
16+
import { IButtonProps, IconButton } from '@zendeskgarden/react-buttons';
17+
18+
interface IMenuButtonProps extends IButtonProps {
19+
appendToNode: boolean;
20+
placement: IMenuProps['placement'];
21+
}
22+
23+
const MenuButton = forwardRef<HTMLButtonElement, IMenuButtonProps>(
24+
({ appendToNode, placement, ...props }, ref) => {
25+
const theme = useTheme();
26+
const body = useDocument(theme)?.body;
27+
28+
return (
29+
<Tooltip content="Menu" placement={placement} appendToNode={appendToNode ? body : undefined}>
30+
<IconButton {...props} ref={ref}>
31+
<Icon />
32+
</IconButton>
33+
</Tooltip>
34+
);
35+
}
36+
);
37+
38+
MenuButton.displayName = 'MenuButton';
39+
40+
interface IArgs extends Omit<ITooltipProps, 'appendToNode'> {
41+
appendToNode: boolean;
42+
}
43+
44+
export const MenuStory: StoryFn<IArgs> = ({ appendToNode, placement }) => (
45+
<Grid>
46+
<Grid.Row style={{ height: 'calc(100vh - 80px)' }}>
47+
<Grid.Col textAlign="center" alignSelf="center">
48+
<Menu
49+
button={
50+
/* eslint-disable-next-line react/no-unstable-nested-components */
51+
props => <MenuButton appendToNode={appendToNode} placement={placement} {...props} />
52+
}
53+
placement={placement}
54+
>
55+
<Item value="One" />
56+
<Item value="Two" />
57+
<Item value="Three" />
58+
</Menu>
59+
</Grid.Col>
60+
</Grid.Row>
61+
</Grid>
62+
);

packages/tooltips/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"types": "dist/typings/index.d.ts",
2323
"dependencies": {
2424
"@floating-ui/react-dom": "^2.0.0",
25-
"@zendeskgarden/container-tooltip": "^1.0.16",
25+
"@zendeskgarden/container-tooltip": "^2.0.0",
2626
"@zendeskgarden/container-utilities": "^2.0.0",
2727
"polished": "^4.3.1",
2828
"prop-types": "^15.5.7",
@@ -35,6 +35,9 @@
3535
"styled-components": "^5.3.1 || ^6.0.0"
3636
},
3737
"devDependencies": {
38+
"@zendeskgarden/react-buttons": "^9.7.0",
39+
"@zendeskgarden/react-dropdowns": "^9.7.0",
40+
"@zendeskgarden/react-grid": "^9.7.0",
3841
"@zendeskgarden/react-theming": "^9.7.0"
3942
},
4043
"keywords": [

packages/tooltips/src/elements/Tooltip.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* found at http://www.apache.org/licenses/LICENSE-2.0.
66
*/
77

8-
import React, { cloneElement, useRef, useEffect, useContext } from 'react';
8+
import React, { cloneElement, useRef, useEffect, useContext, HTMLAttributes } from 'react';
99
import { createPortal } from 'react-dom';
1010
import PropTypes from 'prop-types';
1111
import { ThemeContext } from 'styled-components';
@@ -48,7 +48,8 @@ export const TooltipComponent = ({
4848
const { isVisible, getTooltipProps, getTriggerProps, openTooltip, closeTooltip } = useTooltip({
4949
id,
5050
delayMilliseconds: delayMS,
51-
isVisible: isInitialVisible
51+
isVisible: isInitialVisible,
52+
triggerRef
5253
});
5354

5455
const controlledIsVisible = getControlledValue(externalIsVisible, isVisible);
@@ -98,16 +99,16 @@ export const TooltipComponent = ({
9899
aria-hidden={!controlledIsVisible}
99100
>
100101
<StyledTooltip
102+
$hasArrow={hasArrow}
103+
$placement={placement}
104+
$size={toSize(size, type)}
105+
$type={type}
101106
{...(getTooltipProps({
102107
'aria-hidden': !controlledIsVisible,
103-
$hasArrow: hasArrow,
104-
$placement: placement,
105-
$size: toSize(size, type),
106-
$type: type,
107108
onBlur: composeEventHandlers(onBlur, () => closeTooltip(0)),
108109
onFocus: composeEventHandlers(onFocus, openTooltip),
109110
...props
110-
}) as any)}
111+
}) as HTMLAttributes<HTMLDivElement>)}
111112
>
112113
{content}
113114
</StyledTooltip>

packages/tooltips/src/styled/StyledTooltip.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ interface IStyledTooltipProps {
2424
$hasArrow: ITooltipProps['hasArrow'];
2525
$placement: Placement;
2626
$size: NonNullable<ITooltipProps['size']>;
27-
$type: NonNullable<ITooltipProps['type']>;
27+
$type: ITooltipProps['type'];
2828
}
2929

3030
const sizeStyles = ({

0 commit comments

Comments
 (0)