Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions packages/main/cypress/specs/Avatar.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -840,46 +840,33 @@ describe("Avatar with Badge", () => {
cy.get("#avatar-with-default-badge-tooltip [ui5-avatar-badge]")
.shadow()
.find(".ui5-avatar-badge-icon")
.then(($icon) => {
cy.wrap($icon[0])
.invoke("prop", "_id")
.then((iconId) => {
cy.get("#avatar-with-default-badge-tooltip [ui5-avatar-badge]")
.shadow()
.find(".ui5-avatar-badge-icon")
.shadow()
.find(`#${iconId}-tooltip`)
.should("contain.text", "Edit");
});
});
.should("have.attr", "title", "Edit");
});

it("uses accessibleName as tooltip text when provided", () => {
it("uses tooltip as tooltip text when provided", () => {
const customTooltip = "Open profile editor";

cy.mount(
<Avatar id="avatar-with-custom-badge-tooltip" initials="AB" size="M">
<AvatarBadge slot="badge" icon="edit" accessibleName={customTooltip}></AvatarBadge>
<AvatarBadge slot="badge" icon="edit" tooltip={customTooltip}></AvatarBadge>
</Avatar>
);

cy.get("#avatar-with-custom-badge-tooltip [ui5-avatar-badge]")
.shadow()
.find(".ui5-avatar-badge-icon")
.shadow()
.find("title")
.should("contain.text", customTooltip);
.should("have.attr", "title", customTooltip);
});

it("does not set badge-level accessible text when icon is invalid", () => {
cy.document().then(doc => {
const badge = doc.createElement("ui5-avatar-badge") as AvatarBadge & { effectiveAccessibleName?: string };
const badge = doc.createElement("ui5-avatar-badge") as AvatarBadge & { effectiveTooltip?: string };
badge.id = "badge-fallback-tooltip";
badge.icon = "non-existent-icon-xyz";
doc.body.appendChild(badge);

cy.wait(100).then(() => {
expect(badge.effectiveAccessibleName).to.be.undefined;
expect(badge.effectiveTooltip).to.be.undefined;
expect(badge.hasAttribute("invalid")).to.be.true;
badge.remove();
});
Expand Down
24 changes: 12 additions & 12 deletions packages/main/src/AvatarBadge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ class AvatarBadge extends UI5Element {
icon?: string;

/**
* Defines the custom text alternative of the badge icon.
* Defines the tooltip text of the badge icon.
*
* **Note:** If not provided, the badge uses the icon accessible name.
* If no icon accessible name is available, a generic fallback text is used.
* @default undefined
* @public
* @since 2.22.0
* @since 2.22.0
*/
@property()
accessibleName?: string;
tooltip?: string;

/**
* Defines the state of the badge, which determines its styling.
Expand Down Expand Up @@ -103,35 +103,35 @@ class AvatarBadge extends UI5Element {
* @private
*/
@property({ noAttribute: true })
effectiveAccessibleName?: string;
effectiveTooltip?: string;

async onBeforeRendering() {
const icon = this.icon;
if (!icon) {
this.invalid = true;
this.effectiveAccessibleName = undefined;
this.effectiveTooltip = undefined;
return;
}

const iconData = getIconDataSync(icon) || await getIconData(icon);
this.invalid = !iconData || iconData === ICON_NOT_FOUND;

if (this.invalid) {
this.effectiveAccessibleName = undefined;
} else if (this.accessibleName) {
// User-provided accessible name takes precedence
this.effectiveAccessibleName = this.accessibleName;
this.effectiveTooltip = undefined;
} else if (this.tooltip) {
// User-provided tooltip takes precedence
this.effectiveTooltip = this.tooltip;
} else if (iconData && iconData !== ICON_NOT_FOUND && iconData.accData) {
// Use the icon's registered i18n label (e.g., message-error -> "Error")
if (iconData.packageName) {
const i18nBundle = await getI18nBundle(iconData.packageName);
this.effectiveAccessibleName = i18nBundle.getText(iconData.accData) || undefined;
this.effectiveTooltip = i18nBundle.getText(iconData.accData) || undefined;
} else {
this.effectiveAccessibleName = iconData.accData.defaultText || undefined;
this.effectiveTooltip = iconData.accData.defaultText || undefined;
}
} else {
// Derive from icon name (e.g., "edit" -> "Edit")
this.effectiveAccessibleName = icon.charAt(0).toUpperCase() + icon.slice(1);
this.effectiveTooltip = icon.charAt(0).toUpperCase() + icon.slice(1);
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions packages/main/src/AvatarBadgeTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export default function AvatarBadgeTemplate(this: AvatarBadge) {
<Icon
name={this.icon}
class="ui5-avatar-badge-icon"
accessibleName={this.effectiveAccessibleName}
showTooltip={true}
title={this.effectiveTooltip}
mode="Image"
></Icon>
)}
Expand Down
6 changes: 3 additions & 3 deletions packages/main/test/pages/Avatar.html
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ <h3>Avatar Badge - With Icons</h3>

<section>
<h3>Avatar Badge - Tooltip Behavior</h3>
<p>The badge tooltip is shown by default from the icon semantic text. You can override it with <code>accessible-name</code>.</p>
<p>The badge tooltip is shown by default from the icon semantic text. You can override it with <code>tooltip</code>.</p>
<div style="display: flex; flex-direction: row; align-items: end; column-gap: 0.5rem;">
<div style="text-align: center;">
<ui5-avatar size="M" initials="DF" color-scheme="Accent6">
Expand All @@ -317,9 +317,9 @@ <h3>Avatar Badge - Tooltip Behavior</h3>
</div>
<div style="text-align: center;">
<ui5-avatar size="M" initials="CT" color-scheme="Accent8">
<ui5-avatar-badge icon="edit" accessible-name="Open profile editor" slot="badge"></ui5-avatar-badge>
<ui5-avatar-badge icon="edit" tooltip="Open profile editor" slot="badge"></ui5-avatar-badge>
</ui5-avatar>
<p style="font-size: 0.75rem;">Custom tooltip (accessible-name)</p>
<p style="font-size: 0.75rem;">Custom tooltip (tooltip)</p>
</div>
</div>
</section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The Avatar can show images.
### With Badge
The Avatar supports visual affordance through badges using the `ui5-avatar-badge` component. Badges can display icons with different value states to indicate status or notifications. **It is recommended to use badges with interactive avatars** for better user experience and accessibility.

`ui5-avatar-badge` displays an icon tooltip by default, based on the icon semantic text. To provide a custom tooltip text, set the badge `accessible-name` property.
`ui5-avatar-badge` displays an icon tooltip by default, based on the icon semantic text. To provide a custom tooltip text, set the badge `tooltip` property.

<WithBadge />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
</ui5-avatar>

<ui5-avatar mode="Interactive" size="M" initials="TT" color-scheme="Accent7">
<ui5-avatar-badge icon="edit" accessible-name="Open profile editor" slot="badge"></ui5-avatar-badge>
<ui5-avatar-badge icon="edit" tooltip="Open profile editor" slot="badge"></ui5-avatar-badge>
</ui5-avatar>

<ui5-avatar mode="Interactive" size="M" icon="employee" color-scheme="Accent10">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function App() {
<Avatar mode="Interactive" size="M" initials="TT" colorScheme="Accent7">
<AvatarBadge
icon="edit"
accessibleName="Open profile editor"
tooltip="Open profile editor"
slot="badge"
></AvatarBadge>
</Avatar>
Expand Down
Loading