diff --git a/packages/main/cypress/specs/AvatarGroup.cy.tsx b/packages/main/cypress/specs/AvatarGroup.cy.tsx index 4f5625a2eb99..0919ff327bdf 100644 --- a/packages/main/cypress/specs/AvatarGroup.cy.tsx +++ b/packages/main/cypress/specs/AvatarGroup.cy.tsx @@ -64,3 +64,62 @@ describe("Avatars", () => { }); }); }); + +describe("Accessibility", () => { + it("checks if accessibleName is properly set and applied as aria-label", () => { + const customLabel = "Development Team Members"; + + cy.mount( + + + + ); + + cy.get("#ag") + .should("have.attr", "accessible-name", customLabel) + .then(($el) => { + const avatarGroup = $el.get(0) as AvatarGroup; + expect(avatarGroup.accessibleName).to.equal(customLabel); + }); + + cy.get("#ag") + .shadow() + .find(".ui5-avatar-group-items") + .should("have.attr", "aria-label", customLabel) + .and("not.have.attr", "aria-labelledby"); + }); + + it("checks if accessibleNameRef is properly set and applied as aria-label", () => { + const labelId = "team-header"; + + cy.mount( + <> +

Quality Assurance Team

+ + + + + + + ); + + cy.get("#ag") + .should("have.attr", "accessible-name-ref", labelId) + .then(($el) => { + const avatarGroup = $el.get(0) as AvatarGroup; + expect(avatarGroup.accessibleNameRef).to.equal(labelId); + }); + + cy.get("#ag") + .shadow() + .find(".ui5-avatar-group-items") + .should("have.attr", "aria-label", "Quality Assurance Team"); + + cy.get("#ag") + .shadow() + .find(".ui5-avatar-group-items") + .should("not.have.attr", "aria-labelledby"); + + cy.get(`#${labelId}`).should("exist"); + }); +}); \ No newline at end of file diff --git a/packages/main/src/AvatarGroup.ts b/packages/main/src/AvatarGroup.ts index e46f545aec70..24a9cc2aeba8 100644 --- a/packages/main/src/AvatarGroup.ts +++ b/packages/main/src/AvatarGroup.ts @@ -36,6 +36,7 @@ import AvatarGroupCss from "./generated/themes/AvatarGroup.css.js"; // Template import AvatarGroupTemplate from "./AvatarGroupTemplate.js"; +import { getEffectiveAriaLabelText } from "@ui5/webcomponents-base/dist/util/AccessibilityTextsHelper.js"; /** * Interface for components that represent an avatar and may be slotted in numerous higher-order components such as `ui5-avatar-group` @@ -200,6 +201,26 @@ class AvatarGroup extends UI5Element { @property({ noAttribute: true }) _overflowButtonText?: string; + /** + * Defines the accessible name of the AvatarGroup. + * When provided, this will override the default aria-label text. + * @default undefined + * @public + * @since 2.12.0 + */ + @property() + accessibleName?: string; + + /** + * Receives id(s) of the elements that describe the AvatarGroup. + * When provided, this will be used as aria-labelledby instead of aria-label. + * @default undefined + * @public + * @since 2.12.0 + */ + @property() + accessibleNameRef?: string; + /** * Defines the items of the component. Use the `ui5-avatar` component as an item. * @@ -265,6 +286,10 @@ class AvatarGroup extends UI5Element { } get _ariaLabelText() { + if (this.accessibleName || this.accessibleNameRef) { + return getEffectiveAriaLabelText(this); + } + // Fallback to existing default behavior const hiddenItemsCount = this.hiddenItems.length; const typeLabelKey = this._isGroup ? AVATAR_GROUP_ARIA_LABEL_GROUP : AVATAR_GROUP_ARIA_LABEL_INDIVIDUAL;