diff --git a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts index 0545c5f536f..f4c67bf7e5a 100755 --- a/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts +++ b/packages/calcite-components/src/components/action-menu/action-menu.e2e.ts @@ -1,7 +1,7 @@ import { newE2EPage } from "@stencil/core/testing"; import { html } from "../../../support/formatting"; import { accessible, defaults, focusable, hidden, reflects, renders, slots } from "../../tests/commonTests"; -import { TOOLTIP_DELAY_MS } from "../tooltip/resources"; +import { TOOLTIP_OPEN_DELAY_MS } from "../tooltip/resources"; import { CSS, SLOTS } from "./resources"; describe("calcite-action-menu", () => { @@ -198,7 +198,7 @@ describe("calcite-action-menu", () => { expect(await tooltip.isVisible()).toBe(false); await trigger.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); expect(await tooltip.isVisible()).toBe(true); diff --git a/packages/calcite-components/src/components/tooltip/TooltipManager.ts b/packages/calcite-components/src/components/tooltip/TooltipManager.ts index 3b8a10ce541..ca008d94b80 100644 --- a/packages/calcite-components/src/components/tooltip/TooltipManager.ts +++ b/packages/calcite-components/src/components/tooltip/TooltipManager.ts @@ -1,6 +1,6 @@ import { getShadowRootNode, isPrimaryPointerButton } from "../../utils/dom"; import { ReferenceElement } from "../../utils/floating-ui"; -import { TOOLTIP_DELAY_MS } from "./resources"; +import { TOOLTIP_OPEN_DELAY_MS, TOOLTIP_CLOSE_DELAY_MS } from "./resources"; import { getEffectiveReferenceElement } from "./utils"; export default class TooltipManager { @@ -14,7 +14,9 @@ export default class TooltipManager { private registeredShadowRootCounts = new WeakMap(); - private hoverTimeout: number = null; + private hoverOpenTimeout: number = null; + + private hoverCloseTimeout: number = null; private hoveredTooltip: HTMLCalciteTooltipElement = null; @@ -80,7 +82,7 @@ export default class TooltipManager { if (activeTooltip?.open) { this.clearHoverTimeout(); - this.closeExistingTooltip(); + this.closeActiveTooltip(); const referenceElement = getEffectiveReferenceElement(activeTooltip); @@ -111,9 +113,9 @@ export default class TooltipManager { this.clickedTooltip = null; if (tooltip) { - this.toggleHoveredTooltip(tooltip, true); + this.openHoveredTooltip(tooltip); } else if (activeTooltip) { - this.toggleHoveredTooltip(activeTooltip, false); + this.closeHoveredTooltip(); } }; @@ -166,12 +168,22 @@ export default class TooltipManager { document.removeEventListener("focusout", this.focusOutHandler, { capture: true }); } + private clearHoverOpenTimeout(): void { + window.clearTimeout(this.hoverOpenTimeout); + this.hoverOpenTimeout = null; + } + + private clearHoverCloseTimeout(): void { + window.clearTimeout(this.hoverCloseTimeout); + this.hoverCloseTimeout = null; + } + private clearHoverTimeout(): void { - window.clearTimeout(this.hoverTimeout); - this.hoverTimeout = null; + this.clearHoverOpenTimeout(); + this.clearHoverCloseTimeout(); } - private closeExistingTooltip(): void { + private closeActiveTooltip(): void { const { activeTooltip } = this; if (activeTooltip?.open) { @@ -180,7 +192,7 @@ export default class TooltipManager { } private toggleFocusedTooltip(tooltip: HTMLCalciteTooltipElement, value: boolean): void { - this.closeExistingTooltip(); + this.closeActiveTooltip(); if (value) { this.clearHoverTimeout(); @@ -197,20 +209,31 @@ export default class TooltipManager { } } - private toggleHoveredTooltip = (tooltip: HTMLCalciteTooltipElement, value: boolean): void => { - this.hoverTimeout = window.setTimeout(() => { - if (this.hoverTimeout === null) { + private openHoveredTooltip = (tooltip: HTMLCalciteTooltipElement): void => { + this.hoverOpenTimeout = window.setTimeout(() => { + if (this.hoverOpenTimeout === null) { return; } - this.closeExistingTooltip(); + this.clearHoverCloseTimeout(); + this.closeActiveTooltip(); if (tooltip !== this.hoveredTooltip) { return; } - this.toggleTooltip(tooltip, value); - }, TOOLTIP_DELAY_MS); + this.toggleTooltip(tooltip, true); + }, TOOLTIP_OPEN_DELAY_MS); + }; + + private closeHoveredTooltip = (): void => { + this.hoverCloseTimeout = window.setTimeout(() => { + if (this.hoverCloseTimeout === null) { + return; + } + + this.closeActiveTooltip(); + }, TOOLTIP_CLOSE_DELAY_MS); }; private queryFocusedTooltip(event: FocusEvent, value: boolean): void { diff --git a/packages/calcite-components/src/components/tooltip/resources.ts b/packages/calcite-components/src/components/tooltip/resources.ts index 8a22e3cbd70..0366090554d 100644 --- a/packages/calcite-components/src/components/tooltip/resources.ts +++ b/packages/calcite-components/src/components/tooltip/resources.ts @@ -2,6 +2,7 @@ export const CSS = { container: "container" }; -export const TOOLTIP_DELAY_MS = 500; +export const TOOLTIP_OPEN_DELAY_MS = 300; +export const TOOLTIP_CLOSE_DELAY_MS = 500; export const ARIA_DESCRIBED_BY = "aria-describedby"; diff --git a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts index 5279716c5a9..f76230a51ed 100644 --- a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts +++ b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts @@ -1,5 +1,5 @@ import { E2EPage, newE2EPage } from "@stencil/core/testing"; -import { TOOLTIP_DELAY_MS } from "../tooltip/resources"; +import { TOOLTIP_OPEN_DELAY_MS, TOOLTIP_CLOSE_DELAY_MS } from "../tooltip/resources"; import { accessible, defaults, hidden, floatingUIOwner, renders } from "../../tests/commonTests"; import { html } from "../../../support/formatting"; import { GlobalTestProps } from "../../tests/utils"; @@ -224,7 +224,7 @@ describe("calcite-tooltip", () => { await ref.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); expect(await tooltip.isVisible()).toBe(true); }); @@ -246,7 +246,7 @@ describe("calcite-tooltip", () => { await ref.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); expect(await tooltip.isVisible()).toBe(true); }); @@ -290,7 +290,7 @@ describe("calcite-tooltip", () => { await page.waitForChanges(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); expect(await tooltip.getProperty("open")).toBe(true); @@ -300,7 +300,7 @@ describe("calcite-tooltip", () => { await page.waitForChanges(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_CLOSE_DELAY_MS); expect(await tooltip.getProperty("open")).toBe(false); }); @@ -419,7 +419,7 @@ describe("calcite-tooltip", () => { await referenceElement.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -456,7 +456,7 @@ describe("calcite-tooltip", () => { await referenceElement.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -497,7 +497,7 @@ describe("calcite-tooltip", () => { el.dispatchEvent(new Event("pointermove")); }); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -555,7 +555,7 @@ describe("calcite-tooltip", () => { el.dispatchEvent(new Event("pointermove")); }); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -584,7 +584,7 @@ describe("calcite-tooltip", () => { await referenceElement.hover(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -627,7 +627,7 @@ describe("calcite-tooltip", () => { await referenceElement.click(); - await page.waitForTimeout(TOOLTIP_DELAY_MS); + await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS); await page.waitForChanges(); @@ -748,25 +748,25 @@ describe("calcite-tooltip", () => { selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS * 0.25, + delay: TOOLTIP_OPEN_DELAY_MS * 0.25, property: "open", value: false, selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS * 0.5, + delay: TOOLTIP_OPEN_DELAY_MS * 0.5, property: "open", value: false, selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS, + delay: TOOLTIP_OPEN_DELAY_MS, property: "open", value: true, selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS + TOOLTIP_DELAY_MS * 0.5, + delay: TOOLTIP_OPEN_DELAY_MS + TOOLTIP_OPEN_DELAY_MS * 0.5, property: "open", value: true, selector: "#ref" @@ -809,25 +809,25 @@ describe("calcite-tooltip", () => { selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS, + delay: TOOLTIP_CLOSE_DELAY_MS, property: "open", value: true, selector: "#ref" }, { - delay: TOOLTIP_DELAY_MS * 0.25, + delay: TOOLTIP_CLOSE_DELAY_MS * 0.25, property: "open", value: true, selector: "#ref2" }, { - delay: TOOLTIP_DELAY_MS * 0.5, + delay: TOOLTIP_CLOSE_DELAY_MS * 0.5, property: "open", value: true, selector: "#ref2" }, { - delay: TOOLTIP_DELAY_MS * 0.5, + delay: TOOLTIP_CLOSE_DELAY_MS * 0.5, property: "open", value: false, selector: "#ref2"