diff --git a/packages/calcite-components/src/components/popover/PopoverManager.ts b/packages/calcite-components/src/components/popover/PopoverManager.ts
index 00f3cda446e..b872f75af11 100644
--- a/packages/calcite-components/src/components/popover/PopoverManager.ts
+++ b/packages/calcite-components/src/components/popover/PopoverManager.ts
@@ -87,7 +87,7 @@ export default class PopoverManager {
};
private clickHandler = (event: PointerEvent): void => {
- if (isKeyboardTriggeredClick(event)) {
+ if (isKeyboardTriggeredClick(event) || event.defaultPrevented) {
return;
}
diff --git a/packages/calcite-components/src/components/popover/popover.e2e.ts b/packages/calcite-components/src/components/popover/popover.e2e.ts
index 14568e116ea..ab7c8425a08 100644
--- a/packages/calcite-components/src/components/popover/popover.e2e.ts
+++ b/packages/calcite-components/src/components/popover/popover.e2e.ts
@@ -368,6 +368,35 @@ describe("calcite-popover", () => {
expect(await popover.getProperty("open")).toBe(true);
});
+ it("should not open popovers if event is prevented", async () => {
+ const page = await newE2EPage();
+
+ await page.setContent(html`
+ Content
+
Button
+ `);
+
+ await page.waitForChanges();
+
+ const popover = await page.find("calcite-popover");
+
+ expect(await popover.getProperty("open")).toBe(false);
+
+ await page.$eval("#ref", (ref) => {
+ ref.addEventListener("click", (event) => {
+ event.preventDefault();
+ });
+ });
+
+ const referenceElement = await page.find("#ref");
+
+ await referenceElement.click();
+
+ await page.waitForChanges();
+
+ expect(await popover.getProperty("open")).toBe(false);
+ });
+
it("should not be visible if reference is hidden", async () => {
const page = await newE2EPage();
diff --git a/packages/calcite-components/src/components/tooltip/TooltipManager.ts b/packages/calcite-components/src/components/tooltip/TooltipManager.ts
index 1c5539ac0be..2f5f68ee73d 100644
--- a/packages/calcite-components/src/components/tooltip/TooltipManager.ts
+++ b/packages/calcite-components/src/components/tooltip/TooltipManager.ts
@@ -97,6 +97,10 @@ export default class TooltipManager {
};
private pointerMoveHandler = (event: PointerEvent): void => {
+ if (event.defaultPrevented) {
+ return;
+ }
+
const composedPath = event.composedPath();
const { activeTooltip } = this;
@@ -129,6 +133,10 @@ export default class TooltipManager {
}
private clickHandler = (event: Event): void => {
+ if (event.defaultPrevented) {
+ return;
+ }
+
this.clickedTooltip = null;
const composedPath = event.composedPath();
const tooltip = this.queryTooltip(composedPath);
@@ -160,6 +168,10 @@ export default class TooltipManager {
};
private focusInHandler = (event: FocusEvent): void => {
+ if (event.defaultPrevented) {
+ return;
+ }
+
const composedPath = event.composedPath();
const tooltip = this.queryTooltip(composedPath);
diff --git a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts
index db017596b8d..99db9e68c6c 100644
--- a/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts
+++ b/packages/calcite-components/src/components/tooltip/tooltip.e2e.ts
@@ -320,6 +320,34 @@ describe("calcite-tooltip", () => {
expect(await positionContainer.isVisible()).toBe(true);
});
+ it("should not open when hover event is prevented", async () => {
+ const page = await newE2EPage();
+
+ await page.setContent(
+ `contentreferenceElement
`,
+ );
+
+ await page.waitForChanges();
+
+ const positionContainer = await page.find(`calcite-tooltip >>> .${CSS.positionContainer}`);
+
+ expect(await positionContainer.isVisible()).toBe(false);
+
+ await page.$eval("#ref", (ref) => {
+ ref.addEventListener("pointermove", (event) => {
+ event.preventDefault();
+ });
+ });
+
+ const ref = await page.find("#ref");
+
+ await ref.hover();
+
+ await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);
+
+ expect(await positionContainer.isVisible()).toBe(false);
+ });
+
it("should honor hover interaction with span inside", async () => {
const page = await newE2EPage();
@@ -426,6 +454,34 @@ describe("calcite-tooltip", () => {
expect(await tooltip.getProperty("open")).toBe(false);
});
+ it("should not open if focus event is prevented", async () => {
+ const page = await newE2EPage();
+
+ await page.setContent(html`
+
+ Content
+
+ `);
+
+ await page.waitForChanges();
+
+ const tooltip = await page.find("calcite-tooltip");
+
+ expect(await tooltip.getProperty("open")).toBe(false);
+
+ await page.$eval("#ref", (ref) => {
+ ref.addEventListener("focusin", (event) => {
+ event.preventDefault();
+ });
+
+ ref.dispatchEvent(new FocusEvent("focusin", { bubbles: true, cancelable: true }));
+ });
+
+ await page.waitForChanges();
+
+ expect(await tooltip.getProperty("open")).toBe(false);
+ });
+
it("should handle mouse events", async () => {
const page = await newE2EPage();
@@ -547,6 +603,45 @@ describe("calcite-tooltip", () => {
await assertEscapeKeyCanceled(page, true);
});
+ it("should not close with ESC key if event is prevented", async () => {
+ const page = await newE2EPage();
+
+ await page.setContent(html`
+ Content
+
+ `);
+
+ await page.waitForChanges();
+
+ const tooltip = await page.find("calcite-tooltip");
+
+ expect(await tooltip.getProperty("open")).toBe(false);
+
+ const referenceElement = await page.find("#ref");
+
+ await referenceElement.focus();
+
+ await referenceElement.hover();
+
+ await page.waitForTimeout(TOOLTIP_OPEN_DELAY_MS);
+
+ await page.waitForChanges();
+
+ expect(await tooltip.getProperty("open")).toBe(true);
+
+ await page.evaluate(() => {
+ document.body.addEventListener("keydown", (event) => {
+ if (event.key === "Escape") {
+ event.preventDefault();
+ }
+ });
+ });
+
+ await dispatchKeydownEvent(page, "#ref", "Escape");
+
+ expect(await tooltip.getProperty("open")).toBe(true);
+ });
+
it("should only open the last focused tooltip", async () => {
const page = await newE2EPage();
@@ -1175,6 +1270,25 @@ describe("calcite-tooltip", () => {
expect(await tooltip.getProperty("open")).toBe(false);
});
+ it("should not open when click event is prevented", async () => {
+ const page = await newE2EPage();
+ await page.setContent(pageContent);
+ await skipAnimations(page);
+ await page.waitForChanges();
+ const tooltip = await page.find("calcite-tooltip");
+
+ await page.$eval("#ref", (ref) => {
+ ref.addEventListener("click", (event) => {
+ event.preventDefault();
+ });
+
+ ref.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
+ });
+
+ await page.waitForChanges();
+ expect(await tooltip.getProperty("open")).toBe(false);
+ });
+
it("should work when focusing on a reference element first", async () => {
const page = await newE2EPage();
await page.setContent(pageContent);