Skip to content

Commit 6ad3db7

Browse files
feat: Customise tooltip offset optional prop (#8988)
1 parent e83249a commit 6ad3db7

File tree

6 files changed

+79
-2
lines changed

6 files changed

+79
-2
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Added an optional `offset` prop to `EuiToolTip` to allow customizing the distance (in pixels) between the tooltip and its anchor.

packages/eui/src/components/tool_tip/__snapshots__/tool_tip.test.tsx.snap

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,45 @@ exports[`EuiToolTip shows tooltip on mouseover and focus 1`] = `
9090
</div>
9191
</body>
9292
`;
93+
94+
exports[`EuiToolTip uses custom offset prop value 1`] = `
95+
<body
96+
class="euiBody-hasPortalContent"
97+
>
98+
<div>
99+
<span
100+
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
101+
>
102+
<button
103+
aria-describedby="generated-id"
104+
data-test-subj="trigger"
105+
>
106+
Trigger
107+
</button>
108+
</span>
109+
</div>
110+
<div
111+
data-euiportal="true"
112+
>
113+
<div
114+
aria-label="aria-label"
115+
class="euiToolTipPopover euiToolTip testClass1 testClass2 emotion-euiToolTip-top-euiTestCss"
116+
data-position="top"
117+
data-test-subj="test subject string"
118+
id="generated-id"
119+
offset="32"
120+
position="top"
121+
role="tooltip"
122+
style="top: -32px; left: -10px;"
123+
>
124+
<div
125+
class="euiToolTip__arrow emotion-euiToolTip__arrow-top"
126+
style="left: 3px; top: 100%;"
127+
/>
128+
<div>
129+
content
130+
</div>
131+
</div>
132+
</div>
133+
</body>
134+
`;

packages/eui/src/components/tool_tip/tool_tip.stories.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import { LOKI_SELECTORS, lokiPlayDecorator } from '../../../.storybook/loki';
1414
import { sleep } from '../../test';
1515
import { EuiFlexGroup } from '../flex';
1616
import { EuiButton } from '../button';
17-
import { EuiToolTip, EuiToolTipProps } from './tool_tip';
17+
import {
18+
EuiToolTip,
19+
EuiToolTipProps,
20+
DEFAULT_TOOLTIP_OFFSET,
21+
} from './tool_tip';
1822

1923
const meta: Meta<EuiToolTipProps> = {
2024
title: 'Display/EuiToolTip',
@@ -47,6 +51,7 @@ const meta: Meta<EuiToolTipProps> = {
4751
repositionOnScroll: false,
4852
title: '',
4953
disableScreenReaderOutput: false,
54+
offset: DEFAULT_TOOLTIP_OFFSET,
5055
},
5156
};
5257
enableFunctionToggleControls(meta, ['onMouseOut']);

packages/eui/src/components/tool_tip/tool_tip.test.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import React, { useRef } from 'react';
1010
import { fireEvent } from '@testing-library/react';
11+
import { userEvent } from '@storybook/test';
1112
import {
1213
render,
1314
waitForEuiToolTipVisible,
@@ -61,6 +62,20 @@ describe('EuiToolTip', () => {
6162
await waitForEuiToolTipVisible();
6263
});
6364

65+
it('uses custom offset prop value', async () => {
66+
const offsetValue = 32;
67+
const { baseElement, getByRole } = render(
68+
<EuiToolTip content="content" offset={offsetValue} {...requiredProps}>
69+
<button data-test-subj="trigger">Trigger</button>
70+
</EuiToolTip>
71+
);
72+
const trigger = getByRole('button');
73+
74+
await userEvent.hover(trigger);
75+
await waitForEuiToolTipVisible();
76+
expect(baseElement).toMatchSnapshot();
77+
});
78+
6479
test('anchor props are rendered', () => {
6580
const { baseElement } = render(
6681
<EuiToolTip

packages/eui/src/components/tool_tip/tool_tip.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export const POSITIONS = ['top', 'right', 'bottom', 'left'] as const;
3131
const DISPLAYS = ['inlineBlock', 'block'] as const;
3232

3333
export type ToolTipDelay = 'regular' | 'long';
34+
export const DEFAULT_TOOLTIP_OFFSET = 16;
3435

3536
const delayToMsMap: { [key in ToolTipDelay]: number } = {
3637
regular: 250,
@@ -121,6 +122,11 @@ export interface EuiToolTipProps extends CommonProps {
121122
* hidden.
122123
*/
123124
onMouseOut?: (event: ReactMouseEvent<HTMLSpanElement, MouseEvent>) => void;
125+
126+
/**
127+
* Offset in pixels from the anchor. Defaults to 16.
128+
*/
129+
offset?: number;
124130
}
125131

126132
interface State {
@@ -220,6 +226,7 @@ export class EuiToolTip extends Component<EuiToolTipProps, State> {
220226

221227
positionToolTip = () => {
222228
const requestedPosition = this.props.position;
229+
const offset = this.props.offset ?? DEFAULT_TOOLTIP_OFFSET;
223230

224231
if (!this.anchor || !this.popover) {
225232
return;
@@ -229,7 +236,7 @@ export class EuiToolTip extends Component<EuiToolTipProps, State> {
229236
anchor: this.anchor,
230237
popover: this.popover,
231238
position: requestedPosition,
232-
offset: 16, // offset popover 16px from the anchor
239+
offset,
233240
arrowConfig: {
234241
arrowWidth: 12,
235242
arrowBuffer: 4,

packages/website/docs/components/display/tooltip.mdx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Generally, tooltips should provide short, **non-essential**, contextual informat
1414
:::
1515

1616
Wrap **EuiToolTip** around any item that you need a tooltip for and provide the `content` and optionally the `title`. The `position` prop will take a suggested position, but will change it if the tooltip gets too close to the edge of the screen.
17+
You can adjust the distance between the tooltip and its anchor using the `offset` prop. By default, this value is `16`.
1718

1819
```tsx interactive
1920
import React from 'react';
@@ -65,6 +66,12 @@ export default () => (
6566
<EuiIcon tabIndex="0" type="warning" title="Icon with tooltip" />
6667
</EuiToolTip>
6768
</p>
69+
<p>
70+
This tooltip has a{' '}
71+
<EuiToolTip position="right" content="Here is some tooltip text" offset={32}>
72+
<EuiLink href="#">custom offset</EuiLink>
73+
</EuiToolTip>
74+
</p>
6875
</EuiText>
6976
</div>
7077
);

0 commit comments

Comments
 (0)