diff --git a/packages/main/cypress/specs/MultiInput.cy.tsx b/packages/main/cypress/specs/MultiInput.cy.tsx index 7f1a81565224..d9ed58baa068 100644 --- a/packages/main/cypress/specs/MultiInput.cy.tsx +++ b/packages/main/cypress/specs/MultiInput.cy.tsx @@ -1,6 +1,7 @@ import SuggestionItem from "../../src/SuggestionItem.js"; import MultiInput from "../../src/MultiInput.js"; import "../../src/Token.js"; +import { MULTIINPUT_VALUE_HELP } from "../../src/generated/i18n/i18n-defaults.js"; describe("MultiInput Web Component", () => { it("creates only one token when typing 'ad' and pressing Enter", () => { @@ -48,4 +49,24 @@ describe("MultiInput Web Component", () => { .should("have.length", 1) .and("have.attr", "text", "ad"); }); + + it("Value Help announcement", () => { + const valueHelpId = "hiddenText-value-help"; + + cy.mount(); + + cy.get("[ui5-multi-input]") + .as("multiInput"); + + cy.get("@multiInput") + .shadow() + .find("input") + .should("have.attr", "aria-describedby") + .and("include", valueHelpId); + + cy.get("@multiInput") + .shadow() + .find(`#${valueHelpId}`) + .should("have.text", MULTIINPUT_VALUE_HELP.defaultText); + }); }); diff --git a/packages/main/src/MultiInput.ts b/packages/main/src/MultiInput.ts index 63b089c58c0f..0d7912990b82 100644 --- a/packages/main/src/MultiInput.ts +++ b/packages/main/src/MultiInput.ts @@ -17,7 +17,7 @@ import { import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import { getScopedVarName } from "@ui5/webcomponents-base/dist/CustomElementsScope.js"; import type { IFormInputElement } from "@ui5/webcomponents-base/dist/features/InputElementsFormSupport.js"; -import { MULTIINPUT_ROLEDESCRIPTION_TEXT, MULTIINPUT_VALUE_HELP_LABEL } from "./generated/i18n/i18n-defaults.js"; +import { MULTIINPUT_ROLEDESCRIPTION_TEXT, MULTIINPUT_VALUE_HELP_LABEL, MULTIINPUT_VALUE_HELP } from "./generated/i18n/i18n-defaults.js"; import Input from "./Input.js"; import MultiInputTemplate from "./MultiInputTemplate.js"; import styles from "./generated/themes/MultiInput.css.js"; @@ -364,10 +364,18 @@ class MultiInput extends Input implements IFormInputElement { return getTokensCountText(this.tokens.length); } + get _valueHelpText() { + return MultiInput.i18nBundle.getText(MULTIINPUT_VALUE_HELP); + } + get _tokensCountTextId() { return `hiddenText-nMore`; } + get _valueHelpTextId() { + return this.showValueHelpIcon ? `hiddenText-value-help` : ""; + } + /** * Returns the placeholder value when there are no tokens. * @protected @@ -381,7 +389,7 @@ class MultiInput extends Input implements IFormInputElement { } get accInfo() { - const ariaDescribedBy = `${this._tokensCountTextId} ${this.suggestionsTextId} ${this.valueStateTextId}`.trim(); + const ariaDescribedBy = `${this._tokensCountTextId} ${this.suggestionsTextId} ${this.valueStateTextId} ${this._valueHelpTextId}`.trim(); return { ...super.accInfo, "ariaRoledescription": this.ariaRoleDescription, diff --git a/packages/main/src/MultiInputTemplate.tsx b/packages/main/src/MultiInputTemplate.tsx index aebc8762f580..d6ee8b24e41a 100644 --- a/packages/main/src/MultiInputTemplate.tsx +++ b/packages/main/src/MultiInputTemplate.tsx @@ -14,6 +14,10 @@ function preContent(this: MultiInput) { return ( <> {this._tokensCountText} + + {this.showValueHelpIcon && + {this._valueHelpText} + } { const innerInput = await mi.shadow$("input"); const tokensCountITextId = `hiddenText-nMore`; const suggestionsITextId = `suggestionsText`; - const ariaDescribedBy = `${tokensCountITextId} ${suggestionsITextId}`; + const valueHelpTextId = "hiddenText-value-help"; await browser.$("#suggestion-token").scrollIntoView(); await innerInput.click(); @@ -404,7 +404,11 @@ describe("ARIA attributes", () => { await innerInput.keys("ArrowDown"); await innerInput.keys("Enter"); - assert.strictEqual(await innerInput.getAttribute("aria-describedby"), ariaDescribedBy, "aria-describedby attribute contains multiple references"); + const ariaDescribedBy = await innerInput.getAttribute("aria-describedby"); + + assert.ok(ariaDescribedBy.includes(tokensCountITextId), "aria-describedby should contain tokens count"); + assert.ok(ariaDescribedBy.includes(suggestionsITextId), "aria-describedby should contain suggestions announcement when suggestions are enabled"); + assert.ok(ariaDescribedBy.includes(valueHelpTextId), "aria-describedby should contain value help announcement when value help is enabled"); }); it("aria-roledescription is set properly", async () => {