Skip to content

Commit 0ee3ae1

Browse files
committed
fix(emcn): announce avatar status in the person's label and keep the name on email-only rows
1 parent 7efb137 commit 0ee3ae1

3 files changed

Lines changed: 18 additions & 8 deletions

File tree

‎apps/sim/app/workspace/[workspaceId]/settings/components/member-list/member-list.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface MemberRowProps {
2828
export function MemberRow({ name, email, image, status, roleControl, menu }: MemberRowProps) {
2929
return (
3030
<div className={ROW_CLASSES}>
31-
<Avatar size='xs' name={name} src={image} aria-hidden />
31+
<Avatar size='xs' name={name} src={image} />
3232
<OverflowText label={email} className='flex-1 text-[var(--text-body)] text-sm' />
3333
<span className={ROW_STATUS_CLASSES}>{status}</span>
3434
{roleControl}

‎packages/emcn/src/components/avatar/avatar.test.tsx‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ describe('Avatar', () => {
7575
expect(view.querySelector('[role="img"]')?.getAttribute('aria-label')).toBe('Ada Lovelace')
7676
})
7777

78+
it('announces a status as part of the person, not as a second image', async () => {
79+
const view = await mount(<Avatar size='sm' name='Ada' status='online' />)
80+
const images = view.querySelectorAll('[role="img"]')
81+
expect(images).toHaveLength(1)
82+
expect(images[0]?.getAttribute('aria-label')).toBe('Ada, online')
83+
expect(view.querySelector('[data-slot="avatar-status"]')?.getAttribute('aria-hidden')).toBe(
84+
'true'
85+
)
86+
})
87+
7888
it('never labels an image with an empty name', async () => {
7989
const view = await mount(<Avatar size='xs' name=' ' />)
8090
expect(view.querySelector('[role="img"]')).toBeNull()

‎packages/emcn/src/components/avatar/avatar.tsx‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,9 @@ type AvatarProps = AvatarBaseProps &
9494
(
9595
| {
9696
/**
97-
* A person's name, used as the accessible label — pass `aria-hidden` where the
98-
* name is already visible beside it. The avatar renders `src` with the name's
99-
* initial as its fallback.
97+
* A person's name, used as the accessible label (with any `status`) — pass
98+
* `aria-hidden` where the name is already visible beside it. The avatar renders
99+
* `src` with the name's initial as its fallback.
100100
*/
101101
name: string
102102
/** Photo for the person; the initial shows while it loads, or if it fails. */
@@ -136,7 +136,9 @@ const Avatar = React.forwardRef<React.ElementRef<typeof AvatarPrimitive.Root>, A
136136
<AvatarPrimitive.Root
137137
ref={ref}
138138
className={cn(avatarVariants({ size }), className)}
139-
{...(label && !hidden ? { role: 'img', 'aria-label': label } : {})}
139+
{...(label && !hidden
140+
? { role: 'img', 'aria-label': status ? `${label}, ${status}` : label }
141+
: {})}
140142
{...props}
141143
>
142144
{name === undefined ? (
@@ -151,10 +153,8 @@ const Avatar = React.forwardRef<React.ElementRef<typeof AvatarPrimitive.Root>, A
151153
{status && (
152154
<span
153155
data-slot='avatar-status'
154-
role='img'
155156
className={cn(avatarStatusVariants({ status, size }))}
156-
aria-label={`Status: ${status}`}
157-
aria-hidden={hidden || undefined}
157+
aria-hidden
158158
/>
159159
)}
160160
</div>

0 commit comments

Comments
 (0)