Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,84 @@ exports[`EuiToolTip anchor props are rendered 1`] = `
</body>
`;

exports[`EuiToolTip delay prop none delay 1`] = `
<body
class="euiBody-hasPortalContent"
>
<div>
<span
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-describedby="generated-id"
data-test-subj="trigger"
>
Trigger
</button>
</span>
</div>
<div
data-euiportal="true"
>
<div
class="euiToolTipPopover euiToolTip emotion-euiToolTip-top"
data-position="top"
id="generated-id"
position="top"
role="tooltip"
style="top: -16px; left: -10px;"
>
<div
class="euiToolTip__arrow emotion-euiToolTip__arrow-top"
style="left: 3px; top: 100%;"
/>
<div>
content
</div>
</div>
</div>
</body>
`;

exports[`EuiToolTip delay prop short delay 1`] = `
<body
class="euiBody-hasPortalContent"
>
<div>
<span
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-describedby="generated-id"
data-test-subj="trigger"
>
Trigger
</button>
</span>
</div>
<div
data-euiportal="true"
>
<div
class="euiToolTipPopover euiToolTip emotion-euiToolTip-top"
data-position="top"
id="generated-id"
position="top"
role="tooltip"
style="top: -16px; left: -10px;"
>
<div
class="euiToolTip__arrow emotion-euiToolTip__arrow-top"
style="left: 3px; top: 100%;"
/>
<div>
content
</div>
</div>
</div>
</body>
`;

exports[`EuiToolTip display prop renders block 1`] = `
<div>
<span
Expand Down Expand Up @@ -91,6 +169,84 @@ exports[`EuiToolTip shows tooltip on mouseover and focus 1`] = `
</body>
`;

exports[`EuiToolTip transition prop fade transition 1`] = `
<body
class="euiBody-hasPortalContent"
>
<div>
<span
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-describedby="generated-id"
data-test-subj="trigger"
>
Trigger
</button>
</span>
</div>
<div
data-euiportal="true"
>
<div
class="euiToolTipPopover euiToolTip emotion-euiToolTip-top-topFade"
data-position="top"
id="generated-id"
position="top"
role="tooltip"
style="top: -16px; left: -10px;"
>
<div
class="euiToolTip__arrow emotion-euiToolTip__arrow-top"
style="left: 3px; top: 100%;"
/>
<div>
content
</div>
</div>
</div>
</body>
`;

exports[`EuiToolTip transition prop none transition 1`] = `
<body
class="euiBody-hasPortalContent"
>
<div>
<span
class="euiToolTipAnchor emotion-euiToolTipAnchor-inlineBlock"
>
<button
aria-describedby="generated-id"
data-test-subj="trigger"
>
Trigger
</button>
</span>
</div>
<div
data-euiportal="true"
>
<div
class="euiToolTipPopover euiToolTip emotion-euiToolTip-top-noAnimation"
data-position="top"
id="generated-id"
position="top"
role="tooltip"
style="top: -16px; left: -10px;"
>
<div
class="euiToolTip__arrow emotion-euiToolTip__arrow-top"
style="left: 3px; top: 100%;"
/>
<div>
content
</div>
</div>
</div>
</body>
`;

exports[`EuiToolTip uses custom offset prop value 1`] = `
<body
class="euiBody-hasPortalContent"
Expand Down
6 changes: 5 additions & 1 deletion packages/eui/src/components/tool_tip/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
*/

export type { ToolTipPositions } from './tool_tip_popover';
export type { EuiToolTipProps } from './tool_tip';
export type {
EuiToolTipProps,
ToolTipDelay,
ToolTipTransition,
} from './tool_tip';
export { EuiToolTip } from './tool_tip';

export type { EuiIconTipProps } from './icon_tip';
Expand Down
29 changes: 29 additions & 0 deletions packages/eui/src/components/tool_tip/tool_tip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const meta: Meta<EuiToolTipProps> = {
args: {
position: 'top',
delay: 'regular',
transition: 'default',
display: 'inlineBlock',
// set up for easier testing/QA
anchorClassName: '',
Expand Down Expand Up @@ -72,6 +73,34 @@ export const Playground: Story = {
}),
};

export const ShortDelay: Story = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think adding these as exported stories is necessary. Looking at the other Storybook stories, it seems to me adding delay and transition as args in the Playground is sufficient.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 8241439. Removed the exported stories (ShortDelay, NoDelay, FadeTransition, NoTransition). The delay and transition props are now available as args in the Playground for testing.

args: {
...Playground.args,
delay: 'short',
},
};

export const NoDelay: Story = {
args: {
...Playground.args,
delay: 'none',
},
};

export const FadeTransition: Story = {
args: {
...Playground.args,
transition: 'fade',
},
};

export const NoTransition: Story = {
args: {
...Playground.args,
transition: 'none',
},
};

/**
* VRT only stories
*/
Expand Down
35 changes: 35 additions & 0 deletions packages/eui/src/components/tool_tip/tool_tip.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ const euiToolTipAnimationHorizontal = (size: string) => keyframes`
}
`;

const euiToolTipAnimationFade = keyframes`
0% {
opacity: 0;
}

100% {
opacity: 1;
}
`;

export const euiToolTipStyles = (euiThemeContext: UseEuiTheme) => {
const { euiTheme, highContrastMode } = euiThemeContext;

Expand Down Expand Up @@ -103,6 +113,31 @@ export const euiToolTipStyles = (euiThemeContext: UseEuiTheme) => {
${animationTiming};
}
`,
// Fade transition positions (no movement, just opacity)
topFade: css`
${euiCanAnimate} {
animation: ${euiToolTipAnimationFade} ${animationTiming};
}
`,
bottomFade: css`
${euiCanAnimate} {
animation: ${euiToolTipAnimationFade} ${animationTiming};
}
`,
leftFade: css`
${euiCanAnimate} {
animation: ${euiToolTipAnimationFade} ${animationTiming};
}
`,
rightFade: css`
${euiCanAnimate} {
animation: ${euiToolTipAnimationFade} ${animationTiming};
}
`,
// No animation
noAnimation: css`
/* No animation - tooltip appears immediately */
`,
// Arrow
euiToolTip__arrow: css`
${arrowStyles._arrowStyles}
Expand Down
52 changes: 52 additions & 0 deletions packages/eui/src/components/tool_tip/tool_tip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,58 @@ describe('EuiToolTip', () => {
expect(container).toMatchSnapshot();
});

describe('delay prop', () => {
test('short delay', async () => {
const { baseElement, getByTestSubject } = render(
<EuiToolTip content="content" delay="short">
<button data-test-subj="trigger">Trigger</button>
</EuiToolTip>
);

fireEvent.mouseOver(getByTestSubject('trigger'));
await waitForEuiToolTipVisible();
expect(baseElement).toMatchSnapshot();
});

test('none delay', async () => {
const { baseElement, getByTestSubject } = render(
<EuiToolTip content="content" delay="none">
<button data-test-subj="trigger">Trigger</button>
</EuiToolTip>
);

fireEvent.mouseOver(getByTestSubject('trigger'));
await waitForEuiToolTipVisible();
expect(baseElement).toMatchSnapshot();
});
});

describe('transition prop', () => {
test('fade transition', async () => {
const { baseElement, getByTestSubject } = render(
<EuiToolTip content="content" transition="fade">
<button data-test-subj="trigger">Trigger</button>
</EuiToolTip>
);

fireEvent.mouseOver(getByTestSubject('trigger'));
await waitForEuiToolTipVisible();
expect(baseElement).toMatchSnapshot();
});

test('none transition', async () => {
const { baseElement, getByTestSubject } = render(
<EuiToolTip content="content" transition="none">
<button data-test-subj="trigger">Trigger</button>
</EuiToolTip>
);

fireEvent.mouseOver(getByTestSubject('trigger'));
await waitForEuiToolTipVisible();
expect(baseElement).toMatchSnapshot();
});
});

describe('aria-describedby', () => {
it('by default, sets an `aria-describedby` on the anchor when the tooltip is visible', async () => {
const { getByTestSubject } = render(
Expand Down
15 changes: 14 additions & 1 deletion packages/eui/src/components/tool_tip/tool_tip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ import { toolTipManager } from './tool_tip_manager';
export const POSITIONS = ['top', 'right', 'bottom', 'left'] as const;
const DISPLAYS = ['inlineBlock', 'block'] as const;

export type ToolTipDelay = 'regular' | 'long';
export type ToolTipDelay = 'regular' | 'long' | 'short' | 'none';
export type ToolTipTransition = 'default' | 'fade' | 'none';
export const DEFAULT_TOOLTIP_OFFSET = 16;

const delayToMsMap: { [key in ToolTipDelay]: number } = {
regular: 250,
long: 250 * 5,
short: 100,
none: 0,
};

interface ToolTipStyles {
Expand Down Expand Up @@ -94,6 +97,13 @@ export interface EuiToolTipProps extends CommonProps {
* Delay before showing tooltip. Good for repeatable items.
*/
delay: ToolTipDelay;
/**
* Type of transition for the tooltip appearance.
* - 'default': Uses the current behavior with movement
* - 'fade': Fades in without movement
* - 'none': Appears immediately without animation
*/
transition?: ToolTipTransition;
/**
* An optional title for your tooltip.
*/
Expand Down Expand Up @@ -175,6 +185,7 @@ export class EuiToolTip extends Component<EuiToolTipProps, State> {
static defaultProps: Partial<EuiToolTipProps> = {
position: 'top',
delay: 'regular',
transition: 'default',
display: 'inlineBlock',
disableScreenReaderOutput: false,
};
Expand Down Expand Up @@ -346,6 +357,7 @@ export class EuiToolTip extends Component<EuiToolTipProps, State> {
content,
title,
delay,
transition,
display,
repositionOnScroll,
disableScreenReaderOutput = false,
Expand Down Expand Up @@ -387,6 +399,7 @@ export class EuiToolTip extends Component<EuiToolTipProps, State> {
id={id}
role="tooltip"
calculatedPosition={calculatedPosition}
transition={transition}
{...rest}
>
<EuiToolTipArrow
Expand Down
Loading
Loading