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:
@@ -1015,6 +1015,7 @@ export const Message = React.memo(
|
|||||||
size="300"
|
size="300"
|
||||||
data-user-id={senderId}
|
data-user-id={senderId}
|
||||||
onClick={onUserClick}
|
onClick={onUserClick}
|
||||||
|
aria-label={`${senderDisplayName}, open profile`}
|
||||||
>
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
userId={senderId}
|
userId={senderId}
|
||||||
|
|||||||
@@ -13,7 +13,13 @@ export function BookmarksTab() {
|
|||||||
<SidebarItem active={opened}>
|
<SidebarItem active={opened}>
|
||||||
<SidebarItemTooltip tooltip="Saved Messages">
|
<SidebarItemTooltip tooltip="Saved Messages">
|
||||||
{(triggerRef) => (
|
{(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} />
|
<Icon src={Icons.Star} filled={opened} />
|
||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ export function CreateTab() {
|
|||||||
<SidebarAvatar
|
<SidebarAvatar
|
||||||
className={menuCords ? ContainerColor({ variant: 'Surface' }) : undefined}
|
className={menuCords ? ContainerColor({ variant: 'Surface' }) : undefined}
|
||||||
as="button"
|
as="button"
|
||||||
|
aria-label="Add Space"
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
outlined
|
outlined
|
||||||
onClick={handleMenu}
|
onClick={handleMenu}
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ export function DirectTab() {
|
|||||||
{(triggerRef) => (
|
{(triggerRef) => (
|
||||||
<SidebarAvatar
|
<SidebarAvatar
|
||||||
as="button"
|
as="button"
|
||||||
|
aria-label="Direct Messages"
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
outlined
|
outlined
|
||||||
onClick={handleDirectClick}
|
onClick={handleDirectClick}
|
||||||
|
|||||||
@@ -54,7 +54,13 @@ export function ExploreTab() {
|
|||||||
<SidebarItem active={exploreSelected}>
|
<SidebarItem active={exploreSelected}>
|
||||||
<SidebarItemTooltip tooltip="Explore Community">
|
<SidebarItemTooltip tooltip="Explore Community">
|
||||||
{(triggerRef) => (
|
{(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} />
|
<Icon src={Icons.Explore} filled={exploreSelected} />
|
||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ export function HomeTab() {
|
|||||||
{(triggerRef) => (
|
{(triggerRef) => (
|
||||||
<SidebarAvatar
|
<SidebarAvatar
|
||||||
as="button"
|
as="button"
|
||||||
|
aria-label="Home"
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
outlined
|
outlined
|
||||||
onClick={handleHomeClick}
|
onClick={handleHomeClick}
|
||||||
|
|||||||
@@ -47,7 +47,13 @@ export function InboxTab() {
|
|||||||
<SidebarItem active={inboxSelected}>
|
<SidebarItem active={inboxSelected}>
|
||||||
<SidebarItemTooltip tooltip="Inbox">
|
<SidebarItemTooltip tooltip="Inbox">
|
||||||
{(triggerRef) => (
|
{(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} />
|
<Icon src={Icons.Inbox} filled={inboxSelected} />
|
||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export function SearchTab() {
|
|||||||
<SidebarItem active={opened}>
|
<SidebarItem active={opened}>
|
||||||
<SidebarItemTooltip tooltip="Search">
|
<SidebarItemTooltip tooltip="Search">
|
||||||
{(triggerRef) => (
|
{(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} />
|
<Icon src={Icons.Search} filled={opened} />
|
||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -184,7 +184,12 @@ export function SettingsTab() {
|
|||||||
<SidebarItem active={settingsOpen}>
|
<SidebarItem active={settingsOpen}>
|
||||||
<SidebarItemTooltip tooltip="User Settings">
|
<SidebarItemTooltip tooltip="User Settings">
|
||||||
{(triggerRef) => (
|
{(triggerRef) => (
|
||||||
<SidebarAvatar as="button" ref={triggerRef} onClick={() => setSettingsOpen(true)}>
|
<SidebarAvatar
|
||||||
|
as="button"
|
||||||
|
ref={triggerRef}
|
||||||
|
aria-label="User Settings"
|
||||||
|
onClick={() => setSettingsOpen(true)}
|
||||||
|
>
|
||||||
<UserAvatar
|
<UserAvatar
|
||||||
userId={userId}
|
userId={userId}
|
||||||
src={avatarUrl}
|
src={avatarUrl}
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ function UnverifiedIndicator() {
|
|||||||
<SidebarAvatar
|
<SidebarAvatar
|
||||||
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
|
className={unverified ? css.UnverifiedAvatar : css.UnverifiedOtherAvatar}
|
||||||
as="button"
|
as="button"
|
||||||
|
aria-label={
|
||||||
|
unverified
|
||||||
|
? 'Unverified device — open settings'
|
||||||
|
: 'Other unverified devices — open settings'
|
||||||
|
}
|
||||||
ref={triggerRef}
|
ref={triggerRef}
|
||||||
outlined
|
outlined
|
||||||
onClick={() => setSettings(true)}
|
onClick={() => setSettings(true)}
|
||||||
|
|||||||
Reference in New Issue
Block a user