From 9e3fc30f6d6daffdebe9468860be7b5548961d2c Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:45:56 +0100 Subject: [PATCH 1/3] fix(web-components): add toggle button tooltips --- .../ic-toggle-button/ic-toggle-button.tsx | 8 +++- .../test/basic/ic-toggle-button.spec.ts | 37 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/packages/web-components/src/components/ic-toggle-button/ic-toggle-button.tsx b/packages/web-components/src/components/ic-toggle-button/ic-toggle-button.tsx index c898d9b5cb1..f6ac094b39c 100644 --- a/packages/web-components/src/components/ic-toggle-button/ic-toggle-button.tsx +++ b/packages/web-components/src/components/ic-toggle-button/ic-toggle-button.tsx @@ -10,6 +10,7 @@ import { Watch, } from "@stencil/core"; import { + inheritAttributes, isSlotUsed, onComponentRequiredPropUndefined, removeDisabledFalse, @@ -47,6 +48,8 @@ const TRACKED_ATTRIBUTES = [ }, }) export class ToggleButton { + private title = ""; + @Element() el: HTMLIcToggleButtonElement; /** @@ -127,6 +130,8 @@ export class ToggleButton { }>; componentWillLoad(): void { + const { title } = inheritAttributes(this.el, ["title"]); + this.title = title; this.syncPropsFromToggleButtonGroup(); } @@ -230,6 +235,7 @@ export class ToggleButton { outline, size, theme, + title, tooltipPlacement, variant, } = this; @@ -255,7 +261,7 @@ export class ToggleButton { aria-pressed={`${checked}`} variant={iconVariant ? "icon-tertiary" : "secondary"} onClick={this.handleClick} - title={accessibleLabel} + title={title || accessibleLabel} aria-label={`${accessibleLabel ? accessibleLabel : label}, ${ checked ? "ticked" : "unticked" }`} diff --git a/packages/web-components/src/components/ic-toggle-button/test/basic/ic-toggle-button.spec.ts b/packages/web-components/src/components/ic-toggle-button/test/basic/ic-toggle-button.spec.ts index 0e0d304bf30..2acb72625e9 100644 --- a/packages/web-components/src/components/ic-toggle-button/test/basic/ic-toggle-button.spec.ts +++ b/packages/web-components/src/components/ic-toggle-button/test/basic/ic-toggle-button.spec.ts @@ -1,5 +1,7 @@ import { newSpecPage } from "@stencil/core/testing"; import { ToggleButton } from "../../ic-toggle-button"; +import { Button } from "../../../ic-button/ic-button"; +import { Tooltip } from "../../../ic-tooltip/ic-tooltip"; describe("ic-toggle-button component", () => { it("should render", async () => { @@ -155,3 +157,38 @@ describe("ic-toggle-button component", () => { expect(window.alert).not.toHaveBeenCalled; }); }); + +describe("ic-toggle-button tooltip", () => { + it("should render the standard tooltip for a non-icon toggle button with title", async () => { + const page = await newSpecPage({ + components: [ToggleButton, Button, Tooltip], + html: ``, + }); + + expect(page.root?.hasAttribute("title")).toBe(false); + + const button = page.root?.shadowRoot?.querySelector("ic-button"); + const tooltip = button?.shadowRoot?.querySelector( + "ic-tooltip" + ) as HTMLIcTooltipElement; + + expect(tooltip).not.toBeNull(); + expect(tooltip.label).toBe("Toggle help"); + expect(tooltip.placement).toBe("top"); + }); + + it("should keep the accessible label as the icon variant tooltip fallback", async () => { + const page = await newSpecPage({ + components: [ToggleButton, Button, Tooltip], + html: ``, + }); + + const button = page.root?.shadowRoot?.querySelector("ic-button"); + const tooltip = button?.shadowRoot?.querySelector( + "ic-tooltip" + ) as HTMLIcTooltipElement; + + expect(tooltip).not.toBeNull(); + expect(tooltip.label).toBe("Refresh the page"); + }); +}); From ec4dbb4c0e7565b276dac30685b5252d0fd7bf59 Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Tue, 22 Sep 2026 00:45:56 +0100 Subject: [PATCH 2/3] test(react): cover toggle button tooltips --- .../IcToggleButton/IcToggleButton.cy.tsx | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx b/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx index f1d22bee6fa..6f5f64ae242 100644 --- a/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx +++ b/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx @@ -454,3 +454,42 @@ describe("IcToggleButton visual regression tests in high contrast mode", () => { }); }); }); + +describe("IcToggleButton tooltip visual regression", () => { + beforeEach(() => { + cy.injectAxe(); + }); + + afterEach(() => { + cy.task("generateReport"); + }); + + it("should render a tooltip on a default toggle button", () => { + mount( +
+ +
+ ); + + cy.checkHydrated(IC_TOGGLE_BUTTON_SELECTOR); + cy.get(IC_TOGGLE_BUTTON_SELECTOR).should("not.have.attr", "title"); + + cy.findShadowEl(IC_TOGGLE_BUTTON_SELECTOR, "ic-button") + .shadow() + .find("ic-tooltip") + .trigger("mouseenter") + .shadow() + .find(".ic-tooltip-container") + .should("be.visible"); + + cy.checkA11yWithWait(undefined, undefined, TOGGLE_BUTTON_AXE_OPTIONS); + cy.compareSnapshot({ + name: "/default-with-tooltip", + testThreshold: setThresholdBasedOnEnv(DEFAULT_TEST_THRESHOLD + 0.032), + }); + }); +}); From 7cfc90c3d8337040a86955591c328fedcb2aa5f1 Mon Sep 17 00:00:00 2001 From: Sylvester Kaczmarek <16242628+sylvesterkaczmarek@users.noreply.github.com> Date: Tue, 22 Sep 2026 22:13:30 +0100 Subject: [PATCH 3/3] test(react): trigger toggle tooltip via button hover --- .../component-tests/IcToggleButton/IcToggleButton.cy.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx b/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx index 6f5f64ae242..0015be3cc5f 100644 --- a/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx +++ b/packages/react/src/component-tests/IcToggleButton/IcToggleButton.cy.tsx @@ -1,4 +1,3 @@ -/* eslint-disable react/jsx-no-bind */ /// import React from "react"; @@ -478,10 +477,15 @@ describe("IcToggleButton tooltip visual regression", () => { cy.checkHydrated(IC_TOGGLE_BUTTON_SELECTOR); cy.get(IC_TOGGLE_BUTTON_SELECTOR).should("not.have.attr", "title"); + cy.findShadowEl(IC_TOGGLE_BUTTON_SELECTOR, "ic-button") + .shadow() + .find("button") + .focus() + .trigger("mouseover"); + cy.findShadowEl(IC_TOGGLE_BUTTON_SELECTOR, "ic-button") .shadow() .find("ic-tooltip") - .trigger("mouseenter") .shadow() .find(".ic-tooltip-container") .should("be.visible");