Skip to content

Commit

Permalink
Tooltip fixes on hover and ESC (carbon-design-system#16476)
Browse files Browse the repository at this point in the history
* fix: fixed escape key onMouseEnter

* fix: fix comment onMouseEnter

* fix: fixed hover in the tooltip content

* test: added testing

* fix: removed comment

* test: fixed playwright test

* test: fixed playwright test

* fix: changed to useLayoutEffect to prevent error in SSR

* fix: added useIsomorphicEffect

* fix: fix event propagation
  • Loading branch information
guidari authored May 22, 2024
1 parent 574070e commit db816e6
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 15 deletions.
29 changes: 26 additions & 3 deletions e2e/components/Tooltip/Tooltip-test.avt.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ test.describe('@avt Tooltip', () => {
await expect(page).toHaveNoACViolations('Tooltip - duration');
});

// Prevent timeout
test.slow('@avt-keyboard-nav - tooltip default', async ({ page }) => {
test('@avt-keyboard-nav - tooltip default', async ({ page }) => {
await visitStory(page, {
component: 'Tooltip',
id: 'components-tooltip--default',
Expand All @@ -54,12 +53,36 @@ test.describe('@avt Tooltip', () => {
},
});

await page.keyboard.press('Tab');
await expect(page.getByRole('button')).toBeVisible();
// Expect tooltip to be focused
await page.keyboard.press('Tab');
await expect(page.getByRole('button')).toBeFocused();
// Expect tooltip content to be visible
await expect(page.locator('.cds--popover-container')).toBeVisible();
});

test('@avt-keyboard-nav - tooltip default Escape key on hover', async ({
page,
}) => {
await visitStory(page, {
component: 'Tooltip',
id: 'components-tooltip--default',
globals: {
theme: 'white',
},
});

const tooltipTrigger = page.getByRole('button');
await expect(tooltipTrigger).toBeVisible();

await tooltipTrigger.hover();

const tooltipContent = page.getByText(
'Occasionally, services are updated in a specified time window to ensure no down time for customers.'
);
await expect(tooltipContent).toBeVisible();
// Press ESCAPE key while hover is active
await page.keyboard.press('Escape');
await expect(tooltipContent).toBeHidden();
});
});
48 changes: 36 additions & 12 deletions packages/react/src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useId } from '../../internal/useId';
import { useNoInteractiveChildren } from '../../internal/useNoInteractiveChildren';
import { usePrefix } from '../../internal/usePrefix';
import { type PolymorphicProps } from '../../types/common';
import useIsomorphicEffect from '../../internal/useIsomorphicEffect';

/**
* Event types that trigger a "drag" to stop.
Expand Down Expand Up @@ -144,19 +145,40 @@ function Tooltip<T extends React.ElementType>({
triggerProps['aria-describedby'] = id;
}

function onKeyDown(event: React.KeyboardEvent) {
if (open && match(event, keys.Escape)) {
event.stopPropagation();
setOpen(false);
const onKeyDown = useCallback(
(event: React.SyntheticEvent | Event) => {
if (open && match(event, keys.Escape)) {
event.stopPropagation();
setOpen(false);
}
if (
open &&
closeOnActivation &&
(match(event, keys.Enter) || match(event, keys.Space))
) {
setOpen(false);
}
},
[closeOnActivation, open, setOpen]
);

useIsomorphicEffect(() => {
if (!open) {
return undefined;
}
if (
open &&
closeOnActivation &&
(match(event, keys.Enter) || match(event, keys.Space))
) {
setOpen(false);

function handleKeyDown(event: KeyboardEvent) {
if (match(event, keys.Escape)) {
onKeyDown(event);
}
}
}

document.addEventListener('keydown', handleKeyDown);

return () => {
document.removeEventListener('keydown', handleKeyDown);
};
}, [open, onKeyDown]);

function onMouseEnter() {
// Interactive Tags should not support onMouseEnter
Expand Down Expand Up @@ -221,7 +243,8 @@ function Tooltip<T extends React.ElementType>({
}, [isDragging, onDragStop]);

return (
<Popover<any>
// @ts-ignore-error Popover throws a TS error everytime is imported
<Popover
{...rest}
align={align}
className={cx(`${prefix}--tooltip`, customClassName)}
Expand All @@ -242,6 +265,7 @@ function Tooltip<T extends React.ElementType>({
aria-hidden={open ? 'false' : 'true'}
className={`${prefix}--tooltip-content`}
id={id}
onMouseEnter={onMouseEnter}
role="tooltip">
{label || description}
</PopoverContent>
Expand Down

0 comments on commit db816e6

Please sign in to comment.