a11y: give every icon-only sidebar avatar button and the message sender avatar an accessible name (#185)

axe-core flagged 18 'button-name' criticals on the room view: the space
tabs, Home/Direct/Inbox/Search/Saved/Explore/Add Space/User Settings/
Unverified sidebar buttons, and each message's avatar button had no text
for screen readers. Labels mirror the existing tooltips; message avatars
read '<name>, open profile'. Room view now has zero button-name findings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
2026-09-18 19:17:32 -04:00
co-authored by Claude Opus 5
parent e0b1c50155
commit e9d419f84c
10 changed files with 37 additions and 5 deletions
@@ -1015,6 +1015,7 @@ export const Message = React.memo(
size="300"
data-user-id={senderId}
onClick={onUserClick}
aria-label={`${senderDisplayName}, open profile`}
>
<UserAvatar
userId={senderId}
@@ -13,7 +13,13 @@ export function BookmarksTab() {
<SidebarItem active={opened}>
<SidebarItemTooltip tooltip="Saved Messages">
{(triggerRef) => (
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={toggle}>
<SidebarAvatar
as="button"
ref={triggerRef}
aria-label="Saved Messages"
outlined
onClick={toggle}
>
<Icon src={Icons.Star} filled={opened} />
</SidebarAvatar>
)}
@@ -104,6 +104,7 @@ export function CreateTab() {
<SidebarAvatar
className={menuCords ? ContainerColor({ variant: 'Surface' }) : undefined}
as="button"
aria-label="Add Space"
ref={triggerRef}
outlined
onClick={handleMenu}
@@ -97,6 +97,7 @@ export function DirectTab() {
{(triggerRef) => (
<SidebarAvatar
as="button"
aria-label="Direct Messages"
ref={triggerRef}
outlined
onClick={handleDirectClick}
+7 -1
View File
@@ -54,7 +54,13 @@ export function ExploreTab() {
<SidebarItem active={exploreSelected}>
<SidebarItemTooltip tooltip="Explore Community">
{(triggerRef) => (
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleExploreClick}>
<SidebarAvatar
as="button"
ref={triggerRef}
aria-label="Explore Community"
outlined
onClick={handleExploreClick}
>
<Icon src={Icons.Explore} filled={exploreSelected} />
</SidebarAvatar>
)}
+1
View File
@@ -99,6 +99,7 @@ export function HomeTab() {
{(triggerRef) => (
<SidebarAvatar
as="button"
aria-label="Home"
ref={triggerRef}
outlined
onClick={handleHomeClick}
+7 -1
View File
@@ -47,7 +47,13 @@ export function InboxTab() {
<SidebarItem active={inboxSelected}>
<SidebarItemTooltip tooltip="Inbox">
{(triggerRef) => (
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={handleInboxClick}>
<SidebarAvatar
as="button"
ref={triggerRef}
aria-label="Inbox"
outlined
onClick={handleInboxClick}
>
<Icon src={Icons.Inbox} filled={inboxSelected} />
</SidebarAvatar>
)}
+1 -1
View File
@@ -13,7 +13,7 @@ export function SearchTab() {
<SidebarItem active={opened}>
<SidebarItemTooltip tooltip="Search">
{(triggerRef) => (
<SidebarAvatar as="button" ref={triggerRef} outlined onClick={open}>
<SidebarAvatar as="button" ref={triggerRef} aria-label="Search" outlined onClick={open}>
<Icon src={Icons.Search} filled={opened} />
</SidebarAvatar>
)}
+6 -1
View File
@@ -184,7 +184,12 @@ export function SettingsTab() {
<SidebarItem active={settingsOpen}>
<SidebarItemTooltip tooltip="User Settings">
{(triggerRef) => (
<SidebarAvatar as="button" ref={triggerRef} onClick={() => setSettingsOpen(true)}>
<SidebarAvatar
as="button"
ref={triggerRef}
aria-label="User Settings"
onClick={() => setSettingsOpen(true)}
>
<UserAvatar
userId={userId}
src={avatarUrl}
@@ -54,6 +54,11 @@ function UnverifiedIndicator() {
<SidebarAvatar
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
as="button"
aria-label={
unverified
? 'Unverified device — open settings'
: 'Other unverified devices — open settings'
}
ref={triggerRef}
outlined
onClick={() => setSettings(true)}