diff --git a/packages/main/cypress/specs/Avatar.cy.tsx b/packages/main/cypress/specs/Avatar.cy.tsx index 1c956c632729..5888ebddbddd 100644 --- a/packages/main/cypress/specs/Avatar.cy.tsx +++ b/packages/main/cypress/specs/Avatar.cy.tsx @@ -21,6 +21,71 @@ describe("Accessibility", () => { .should("have.attr", "aria-label", expectedLabel); }); + it("should return correct accessibilityInfo object when avatar is interactive", () => { + const INITIALS = "JD"; + const hasPopup = "menu"; + const customLabel = "John Doe Avatar"; + + cy.mount( + + ); + + cy.get("#interactive-info").then($avatar => { + const avatar = $avatar[0] as any; + + // Check accessibilityInfo properties + expect(avatar.accessibilityInfo).to.exist; + expect(avatar.accessibilityInfo.role).to.equal("button"); + expect(avatar.accessibilityInfo.type).to.equal("Button"); + expect(avatar.accessibilityInfo.description).to.equal(customLabel); + }); + }); + + it("should return correct accessibilityInfo object when avatar is not interactive", () => { + cy.mount( + + ); + + cy.get("#non-interactive-info").then($avatar => { + const avatar = $avatar[0] as any; + + // Check that accessibilityInfo is undefined + expect(avatar.accessibilityInfo).to.exist; + expect(avatar.accessibilityInfo.role).to.equal("img"); + expect(avatar.accessibilityInfo.type).to.equal("Image"); + expect(avatar.accessibilityInfo.description).to.equal("Avatar JD"); + }); + }); + + it("should use default label for accessibilityInfo description when no custom label is provided", () => { + const INITIALS = "AB"; + + cy.mount( + + ); + + cy.get("#default-label-info").then($avatar => { + const avatar = $avatar[0] as any; + + // Check that accessibilityInfo uses the default label format that includes initials + expect(avatar.accessibilityInfo).to.exist; + expect(avatar.accessibilityInfo.description).to.equal(`Avatar ${INITIALS}`); + }); + }); + it("checks if accessible-name is correctly passed to the icon", () => { const ACCESSIBLE_NAME = "Supplier Icon"; const ICON_NAME = "supplier"; @@ -500,4 +565,4 @@ describe("Avatar Rendering and Interaction", () => { cy.get("@clickStub") .should("have.been.calledOnce"); }); -}); \ No newline at end of file +}); diff --git a/packages/main/src/Avatar.ts b/packages/main/src/Avatar.ts index 6d18d798d759..9a80c0d1e93f 100644 --- a/packages/main/src/Avatar.ts +++ b/packages/main/src/Avatar.ts @@ -5,7 +5,7 @@ import slot from "@ui5/webcomponents-base/dist/decorators/slot.js"; import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js"; import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import type { AccessibilityAttributes } from "@ui5/webcomponents-base/dist/types.js"; +import type { AccessibilityAttributes, AriaRole } from "@ui5/webcomponents-base/dist/types.js"; import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import type { ITabbable } from "@ui5/webcomponents-base/dist/delegate/ItemNavigation.js"; import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js"; @@ -17,7 +17,11 @@ import type { IAvatarGroupItem } from "./AvatarGroup.js"; // Template import AvatarTemplate from "./AvatarTemplate.js"; -import { AVATAR_TOOLTIP } from "./generated/i18n/i18n-defaults.js"; +import { + AVATAR_TOOLTIP, + AVATAR_TYPE_BUTTON, + AVATAR_TYPE_IMAGE, +} from "./generated/i18n/i18n-defaults.js"; // Styles import AvatarCss from "./generated/themes/Avatar.css.js"; @@ -493,6 +497,15 @@ class Avatar extends UI5Element implements ITabbable, IAvatarGroupItem { } this._imageLoadError = true; } + + get accessibilityInfo() { + return { + role: this._role as AriaRole, + type: this.interactive ? Avatar.i18nBundle.getText(AVATAR_TYPE_BUTTON) : Avatar.i18nBundle.getText(AVATAR_TYPE_IMAGE), + description: this.accessibleNameText, + disabled: this.disabled, + }; + } } Avatar.define(); diff --git a/packages/main/src/i18n/messagebundle.properties b/packages/main/src/i18n/messagebundle.properties index 4ec85cc590c2..72216cb1f5ac 100644 --- a/packages/main/src/i18n/messagebundle.properties +++ b/packages/main/src/i18n/messagebundle.properties @@ -16,6 +16,12 @@ ARIA_ROLEDESCRIPTION_INTERACTIVE_CARD_HEADER=Interactive Card Header #XACT: ARIA announcement for the Avatar default tooltip AVATAR_TOOLTIP=Avatar +#XACT: ARIA type description for interactive Avatar (when the Avatar is a button) +AVATAR_TYPE_BUTTON=Button + +#XACT: ARIA type description for non-interactive Avatar (when the Avatar is an image) +AVATAR_TYPE_IMAGE=Image + #XACT: ARIA announcement for the Avatar default tooltip AVATAR_GROUP_DISPLAYED_HIDDEN_LABEL={0} displayed, {1} hidden.