Skip to content

Commit

Permalink
chore: Fix display of multiple tooltips
Browse files Browse the repository at this point in the history
  • Loading branch information
Francesco Longo committed Sep 11, 2024
1 parent 63d9ef7 commit 96ccee6
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 9 deletions.
39 changes: 39 additions & 0 deletions src/breadcrumb-group/__integ__/breadcrumb-group.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ class BreadcrumbGroupPage extends BasePageObject {
isTooltipDisplayed() {
return this.isExisting(`.${tooltipStyles.root}`);
}
countTooltips() {
return this.browser.execute(function (selector) {
return Array.from(document.querySelectorAll(selector)).length;
}, `.${tooltipStyles.root}`);
}
getTooltipText() {
return this.getText(`.${tooltipStyles.root}`);
}
}
const setupTest = (
testFn: (page: BreadcrumbGroupPage, browser: WebdriverIO.Browser) => Promise<void>,
Expand Down Expand Up @@ -244,4 +252,35 @@ describe('BreadcrumbGroup', () => {
await expect(page.getActiveElementId()).resolves.toBe('focus-target-short-text');
})
);

test(
'Displays only one tooltip at the time',
setupTest(async page => {
await page.setMobileViewport();
await page.click('#focus-target-long-text');
await page.keys('Tab');
await expect(page.countTooltips()).resolves.toBe(1);
await expect(page.getTooltipText()).resolves.toBe(
'First that is very very very very very very long long long text'
);
await page.hoverElement(breadcrumbGroupWrapper.findBreadcrumbLink(6).toSelector());
await expect(page.countTooltips()).resolves.toBe(1);
await expect(page.getTooltipText()).resolves.toBe(
'Sixth that is very very very very very very long long long text'
);

await page.click('#focus-target-long-text');
await expect(page.countTooltips()).resolves.toBe(0);
await page.hoverElement(breadcrumbGroupWrapper.findBreadcrumbLink(6).toSelector());
await expect(page.countTooltips()).resolves.toBe(1);
await expect(page.getTooltipText()).resolves.toBe(
'Sixth that is very very very very very very long long long text'
);
await page.keys('Tab');
await expect(page.countTooltips()).resolves.toBe(1);
await expect(page.getTooltipText()).resolves.toBe(
'First that is very very very very very very long long long text'
);
})
);
});
37 changes: 37 additions & 0 deletions src/breadcrumb-group/__tests__/tooltips-resgistry.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { fireEvent } from '@testing-library/react';

import { registerTooltip } from '../item/tooltips-registry';

describe('registerTooltip', () => {
test('calls previous callbacks when registering new callback', () => {
const callbackOne = jest.fn();
const callbackTwo = jest.fn();
const callbackThree = jest.fn();
registerTooltip(callbackOne);
registerTooltip(callbackTwo);
registerTooltip(callbackThree);
expect(callbackThree).toBeCalledTimes(0);
expect(callbackTwo).toBeCalledTimes(1);
expect(callbackOne).toBeCalledTimes(2);
});
test('does not call deregistered callbacks', () => {
const callbackOne = jest.fn();
const callbackTwo = jest.fn();
const deregisterOne = registerTooltip(callbackOne);
deregisterOne();
registerTooltip(callbackTwo);
expect(callbackTwo).toBeCalledTimes(0);
expect(callbackOne).toBeCalledTimes(0);
});
test('calls callbacks upon clicking on ESC', () => {
const callbackOne = jest.fn();
const deregisterOne = registerTooltip(callbackOne);
fireEvent.keyDown(document, { key: 'Escape' });
expect(callbackOne).toBeCalledTimes(1);
deregisterOne();
fireEvent.keyDown(document, { key: 'Escape' });
expect(callbackOne).toBeCalledTimes(1);
});
});
13 changes: 4 additions & 9 deletions src/breadcrumb-group/item/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { fireCancelableEvent, isPlainLeftClick } from '../../internal/events';
import { BreadcrumbGroupProps, BreadcrumbItemProps } from '../interfaces';
import { getEventDetail } from '../utils';
import { FunnelBreadcrumbItem } from './funnel';
import { registerTooltip } from './tooltips-registry';

import styles from './styles.css.js';

Expand All @@ -28,17 +29,11 @@ const BreadcrumbItemWithPopover = <T extends BreadcrumbGroupProps.Item>({
const popoverContent = <Tooltip trackRef={textRef} value={item.text} />;

useEffect(() => {
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
setShowPopover(false);
}
};
if (showPopover) {
document.addEventListener('keydown', onKeyDown);
return registerTooltip(() => {
setShowPopover(false);
});
}
return () => {
document.removeEventListener('keydown', onKeyDown);
};
}, [showPopover]);

return (
Expand Down
33 changes: 33 additions & 0 deletions src/breadcrumb-group/item/tooltips-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

type OnClose = () => void;

let callbacks: Array<OnClose> = [];
let listenerRegistered = false;

const onKeyDown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
callbacks.forEach(callback => callback());
}
};

export const registerTooltip = (onClose: OnClose) => {
callbacks.forEach(callback => callback());
callbacks.push(onClose);
if (!listenerRegistered) {
listenerRegistered = true;
document.addEventListener('keydown', onKeyDown);
}
return () => {
deregisterTooltip(onClose);
};
};

const deregisterTooltip = (onClose: OnClose) => {
callbacks = callbacks.filter(callback => callback !== onClose);
if (listenerRegistered && callbacks.length === 0) {
listenerRegistered = false;
document.removeEventListener('keydown', onKeyDown);
}
};

0 comments on commit 96ccee6

Please sign in to comment.