Skip to content

Commit 3af6dc6

Browse files
authored
fix(a11y): missing default alt text for avatar (#4243)
1 parent a46ce07 commit 3af6dc6

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

framework/core/js/src/common/components/Avatar.tsx

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ export default class Avatar<CustomAttrs extends IAvatarAttrs = IAvatarAttrs> ext
1919
// If the `title` attribute is set to null or false, we don't want to give the
2020
// avatar a title. On the other hand, if it hasn't been given at all, we can
2121
// safely default it to the user's username.
22-
const hasTitle: boolean | string = attrs.title === 'undefined' || attrs.title;
23-
if (!hasTitle) delete attrs.title;
22+
const hasTitle: boolean | string = (attrs as any).title === 'undefined' || (attrs as any).title;
23+
if (!hasTitle) delete (attrs as any).title;
2424

2525
// If a user has been passed, then we will set up an avatar using their
2626
// uploaded image, or the first letter of their username if they haven't
@@ -29,16 +29,30 @@ export default class Avatar<CustomAttrs extends IAvatarAttrs = IAvatarAttrs> ext
2929
const username = user.displayName() || '?';
3030
const avatarUrl = user.avatarUrl();
3131

32-
if (hasTitle) attrs.title = attrs.title || username;
32+
if (hasTitle) (attrs as any).title = (attrs as any).title || username;
33+
34+
// Alt text logic:
35+
// If the `alt` attribute is set to null or false, we don't want to give the
36+
// avatar an alt description. If it hasn't been provided, we'll default it to
37+
// the user's display name *when rendering an <img>* so screen readers have context.
38+
const hasAlt: boolean | string = (attrs as any).alt === 'undefined' || (attrs as any).alt;
39+
if (!hasAlt) delete (attrs as any).alt;
3340

3441
if (avatarUrl) {
35-
return <img {...attrs} src={avatarUrl} alt="" />;
42+
// Default alt to username unless explicitly overridden.
43+
if ((attrs as any).alt === undefined) {
44+
(attrs as any).alt = username;
45+
}
46+
47+
return <img {...attrs} src={avatarUrl} />;
3648
}
3749

3850
content = username.charAt(0).toUpperCase();
3951
attrs.style = !window.testing && { '--avatar-bg': user.color() };
4052
}
4153

54+
// Note: We intentionally do NOT set `alt` when rendering the fallback <span>,
55+
// as `alt` is only valid for certain elements (e.g., <img>, <area>, <input type="image">).
4256
return <span {...attrs}>{content}</span>;
4357
}
4458
}

0 commit comments

Comments
 (0)