Skip to content

Commit

Permalink
feat(tooltip): support touch events (#9487)
Browse files Browse the repository at this point in the history
**Related Issue:** #9273

## Summary

- support tap/touch events for tooltip
- cleanup
- removed private vars for hoveredTooltip, clickedTooltip to simplify
things
- add test
  • Loading branch information
driskull authored and github-actions[bot] committed Jul 30, 2024
1 parent 92f31bf commit 633706b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ export default class TooltipManager {

private hoverCloseTimeout: number = null;

private hoveredTooltip: HTMLCalciteTooltipElement = null;

private clickedTooltip: HTMLCalciteTooltipElement = null;

private activeTooltip: HTMLCalciteTooltipElement = null;

private registeredElementCount = 0;
Expand Down Expand Up @@ -96,38 +92,52 @@ export default class TooltipManager {
private pointerMoveHandler = (event: PointerEvent): void => {
const composedPath = event.composedPath();
const { activeTooltip } = this;
const hoveringActiveTooltip = activeTooltip?.open && composedPath.includes(activeTooltip);

if (hoveringActiveTooltip) {
this.clearHoverTimeout();
return;
}

const tooltip = this.queryTooltip(composedPath);
this.hoveredTooltip = tooltip;

if (this.isClosableClickedTooltip(tooltip)) {
if (this.pathHasOpenTooltip(tooltip, composedPath)) {
this.clearHoverTimeout();
return;
}

this.clickedTooltip = null;

if (tooltip) {
this.openHoveredTooltip(tooltip);
} else if (activeTooltip) {
} else if (activeTooltip?.open) {
this.closeHoveredTooltip();
}
};

private clickHandler = (event: PointerEvent): void => {
const clickedTooltip = this.queryTooltip(event.composedPath());
private pathHasOpenTooltip(tooltip: HTMLCalciteTooltipElement, composedPath: EventTarget[]): boolean {
const { activeTooltip } = this;

this.clickedTooltip = clickedTooltip;
return (
(activeTooltip?.open && composedPath.includes(activeTooltip)) || (tooltip?.open && composedPath.includes(tooltip))
);
}

if (clickedTooltip?.closeOnClick) {
this.toggleTooltip(clickedTooltip, false);
private clickHandler = (event: Event): void => {
const composedPath = event.composedPath();
const tooltip = this.queryTooltip(composedPath);

if (this.pathHasOpenTooltip(tooltip, composedPath)) {
this.clearHoverTimeout();
return;
}

this.closeActiveTooltip();

if (!tooltip) {
return;
}

this.clearHoverTimeout();

if (tooltip.closeOnClick) {
this.toggleTooltip(tooltip, false);
return;
}

this.toggleTooltip(tooltip, true);
};

private focusInHandler = (event: FocusEvent): void => {
Expand Down Expand Up @@ -179,6 +189,12 @@ export default class TooltipManager {
this.clearHoverCloseTimeout();
}

private closeTooltipIfNotActive(tooltip: HTMLCalciteTooltipElement): void {
if (this.activeTooltip !== tooltip) {
this.closeActiveTooltip();
}
}

private closeActiveTooltip(): void {
const { activeTooltip } = this;

Expand All @@ -188,8 +204,6 @@ export default class TooltipManager {
}

private toggleFocusedTooltip(tooltip: HTMLCalciteTooltipElement, open: boolean): void {
this.closeActiveTooltip();

if (open) {
this.clearHoverTimeout();
}
Expand All @@ -211,20 +225,10 @@ export default class TooltipManager {
}

this.clearHoverCloseTimeout();

if (this.activeTooltip === this.hoveredTooltip) {
return;
}

this.closeActiveTooltip();

if (tooltip !== this.hoveredTooltip) {
return;
}

this.closeTooltipIfNotActive(tooltip);
this.toggleTooltip(tooltip, true);
},
this.activeTooltip ? 0 : TOOLTIP_OPEN_DELAY_MS,
this.activeTooltip?.open ? 0 : TOOLTIP_OPEN_DELAY_MS,
);
};

Expand All @@ -239,19 +243,18 @@ export default class TooltipManager {
};

private queryFocusedTooltip(event: FocusEvent, open: boolean): void {
const tooltip = this.queryTooltip(event.composedPath());
const composedPath = event.composedPath();
const tooltip = this.queryTooltip(composedPath);

this.closeTooltipIfNotActive(tooltip);

if (!tooltip || this.isClosableClickedTooltip(tooltip)) {
if (!tooltip) {
return;
}

this.toggleFocusedTooltip(tooltip, open);
}

private isClosableClickedTooltip(tooltip: HTMLCalciteTooltipElement): boolean {
return tooltip?.closeOnClick && tooltip === this.clickedTooltip;
}

private registerShadowRoot(shadowRoot: ShadowRoot): void {
const { registeredShadowRootCounts } = this;

Expand Down
48 changes: 39 additions & 9 deletions packages/calcite-components/src/components/tooltip/tooltip.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ describe("calcite-tooltip", () => {
expect(await tooltip.getProperty("open")).toBe(false);
});

it("should not open tooltip when clicked", async () => {
it("should handle mouse events", async () => {
const page = await newE2EPage();

await page.setContent(html`
Expand All @@ -388,7 +388,37 @@ describe("calcite-tooltip", () => {

await page.evaluate(() => {
const ref = document.getElementById("ref");
ref.click();
const event1 = new MouseEvent("click", {
cancelable: true,
bubbles: true,
});
ref.dispatchEvent(event1);
});

await page.waitForChanges();

expect(await tooltip.getProperty("open")).toBe(true);

await page.evaluate(() => {
const ref = document.getElementById("ref");
const event1 = new MouseEvent("click", {
cancelable: true,
bubbles: true,
});
ref.dispatchEvent(event1);
});

await page.waitForChanges();

expect(await tooltip.getProperty("open")).toBe(true);

await page.evaluate(() => {
const ref = document.getElementById("test");
const event1 = new MouseEvent("click", {
cancelable: true,
bubbles: true,
});
ref.dispatchEvent(event1);
});

await page.waitForChanges();
Expand Down Expand Up @@ -516,7 +546,7 @@ describe("calcite-tooltip", () => {
expect(await hoverTip.getProperty("open")).toBe(false);

await page.$eval("#hoverRef", (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});

await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);
Expand Down Expand Up @@ -572,7 +602,7 @@ describe("calcite-tooltip", () => {
expect(await hoverTip.getProperty("open")).toBe(false);

await page.$eval("#hoverRef", (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});

await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);
Expand Down Expand Up @@ -911,7 +941,7 @@ describe("calcite-tooltip", () => {
const { delay, selector } = pointerMoves[i];
await page.waitForTimeout(delay);
await page.$eval(selector, (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});

expect(await tooltip.getProperty(pointerMoves[i].property)).toBe(pointerMoves[i].value);
Expand Down Expand Up @@ -970,7 +1000,7 @@ describe("calcite-tooltip", () => {
const { delay, selector } = pointerMoves[i];
await page.waitForTimeout(delay);
await page.$eval(selector, (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});

expect(await tooltip.getProperty(pointerMoves[i].property)).toBe(pointerMoves[i].value);
Expand Down Expand Up @@ -1029,7 +1059,7 @@ describe("calcite-tooltip", () => {
.querySelector("shadow-component-b")
.shadowRoot.querySelector("shadow-component-a")
.shadowRoot.querySelector("button");
referenceElement.dispatchEvent(new Event("focusin"));
referenceElement.dispatchEvent(new FocusEvent("focusin"));
});
}

Expand Down Expand Up @@ -1061,7 +1091,7 @@ describe("calcite-tooltip", () => {
expect(await tooltip2.getProperty("open")).toBe(false);

await page.$eval("#ref1", (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});
await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);
await page.waitForChanges();
Expand All @@ -1070,7 +1100,7 @@ describe("calcite-tooltip", () => {
expect(await tooltip2.getProperty("open")).toBe(false);

await page.$eval("#ref2", (el: HTMLElement) => {
el.dispatchEvent(new Event("pointermove"));
el.dispatchEvent(new PointerEvent("pointermove"));
});
await page.waitForTimeout(0);
await page.waitForChanges();
Expand Down

0 comments on commit 633706b

Please sign in to comment.