Skip to content

Commit

Permalink
fix(avatar): fix role for avatar caontainer
Browse files Browse the repository at this point in the history
  • Loading branch information
Tianhui-Han authored and JudyZhuHz committed Aug 6, 2024
1 parent 39e85a0 commit 083b349
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 120 deletions.
6 changes: 5 additions & 1 deletion src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,18 @@ const Avatar = (props: Props, ref: RefObject<HTMLButtonElement>) => {

const containerAriaLabel = rest['aria-label'] || avatarLabels.join(', ');
delete rest['aria-label'];

const hasPresence = !!presenceIcon;
// If there is a case where the child element needs to be read by the SR, group role is used, otherwise img role is used
const containerRole = hasPresence ? 'group' : 'img';

const content = (
<div
className={classnames(STYLE.wrapper, className)}
data-size={size}
data-color={color}
aria-label={onPress ? undefined : containerAriaLabel}
role='group'
role={containerRole}
{...(!onPress && { ...rest })}
>
{!imageLoaded && !icon && initialsText && (
Expand Down
134 changes: 66 additions & 68 deletions src/components/Avatar/Avatar.unit.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ describe('Avatar', () => {
isPerson,
avatarType,
isTyping,
expectedRole,
expectedLabel,
}) => {
const onPress = withOnPress
Expand All @@ -48,21 +49,22 @@ describe('Avatar', () => {
/>,
);

let assertCount = 1;
let assertCount = 2;

if (withPresence) {
assertCount += 1;
}

expect.assertions(assertCount);

const wrapper = mockAvatar.find('.md-avatar-wrapper');
const container = mockAvatar.find('.md-avatar-wrapper');

expect(container.props().role).toEqual(expectedRole);

if (withOnPress) {
const button = mockAvatar.find('button');
expect(button.props()['aria-label']).toEqual(expectedLabel);
} else {
const container = mockAvatar.find('.md-avatar-wrapper');
expect(container.props()['aria-label']).toEqual(expectedLabel);
}

Expand Down Expand Up @@ -370,23 +372,11 @@ describe('Avatar', () => {
expect(element).toBeDefined();
});

it('container has the default role - group', async () => {
expect.assertions(1);

const container = await mountAndWait(
<Avatar title="Cisco Webex" />
);

const title = container.getDOMNode().getAttribute('role');

expect(title).toBe('group');
});

it('should pass the mainLabel prop', () => {
expect.assertions(1);

const mainLabel = 'avatar of Bob';
const onPress = () => 'h1'
const onPress = () => 'h1';

const element = mount(<Avatar mainLabel={mainLabel} onPress={onPress}/>)
.find('button');
Expand Down Expand Up @@ -440,61 +430,69 @@ describe('Avatar', () => {
expect(element.props()['aria-label']).toBe(mainLabel);
});


it.each`
withOnPress | withPresence | isPerson | avatarType | isTyping | expectedLabel
${true} | ${true} | ${true} | ${'src'} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${'src'} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${true} | ${'icon'} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${'icon'} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${true} | ${null} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${null} | ${true} | ${'Avatar of Name, Active, is typing'}
${true} | ${false} | ${true} | ${'src'} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${'src'} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${true} | ${'icon'} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${'icon'} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${true} | ${null} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${null} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${true} | ${true} | ${'src'} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${'src'} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${true} | ${'icon'} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${'icon'} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${true} | ${null} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${null} | ${true} | ${'Avatar of Name, Active, is typing'}
${false} | ${false} | ${true} | ${'src'} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${'src'} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${true} | ${'icon'} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${'icon'} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${true} | ${null} | ${true} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${null} | ${true} | ${'Avatar of Name, is typing'}
${true} | ${true} | ${true} | ${'src'} | ${false} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${'src'} | ${false} | ${'Avatar of Name, Active'}
${true} | ${true} | ${true} | ${'icon'} | ${false} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${'icon'} | ${false} | ${'Avatar of Name, Active'}
${true} | ${true} | ${true} | ${null} | ${false} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${null} | ${false} | ${'Avatar of Name, Active'}
${true} | ${false} | ${true} | ${'src'} | ${false} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${'src'} | ${false} | ${'Avatar of Name'}
${true} | ${false} | ${true} | ${'icon'} | ${false} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${'icon'} | ${false} | ${'Avatar of Name'}
${true} | ${false} | ${true} | ${null} | ${false} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${null} | ${false} | ${'Avatar of Name'}
${false} | ${true} | ${true} | ${'src'} | ${false} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${'src'} | ${false} | ${'Avatar of Name, Active'}
${false} | ${true} | ${true} | ${'icon'} | ${false} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${'icon'} | ${false} | ${'Avatar of Name, Active'}
${false} | ${true} | ${true} | ${null} | ${false} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${null} | ${false} | ${'Avatar of Name, Active'}
${false} | ${false} | ${true} | ${'src'} | ${false} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'src'} | ${false} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${'icon'} | ${false} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'icon'} | ${false} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${null} | ${false} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${null} | ${false} | ${'Avatar of Name'}
withOnPress | withPresence | isPerson | avatarType | isTyping | expectedRole | expectedLabel
${true} | ${true} | ${true} | ${'src'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${'src'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${true} | ${'icon'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${'icon'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${true} | ${null} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${true} | ${false} | ${null} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${true} | ${false} | ${true} | ${'src'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${'src'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${true} | ${'icon'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${'icon'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${true} | ${null} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${false} | ${false} | ${null} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${true} | ${true} | ${'src'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${'src'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${true} | ${'icon'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${'icon'} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${true} | ${null} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${true} | ${false} | ${null} | ${true} | ${'group'} | ${'Avatar of Name, Active, is typing'}
${false} | ${false} | ${true} | ${'src'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${'src'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${true} | ${'icon'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${'icon'} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${true} | ${null} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${false} | ${false} | ${false} | ${null} | ${true} | ${'img'} | ${'Avatar of Name, is typing'}
${true} | ${true} | ${true} | ${'src'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${'src'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${true} | ${true} | ${'icon'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${'icon'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${true} | ${true} | ${null} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${true} | ${false} | ${null} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${true} | ${false} | ${true} | ${'src'} | ${false} | ${'img'} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${'src'} | ${false} | ${'img'} | ${'Avatar of Name'}
${true} | ${false} | ${true} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${true} | ${false} | ${true} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
${true} | ${false} | ${false} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${true} | ${true} | ${'src'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${'src'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${true} | ${true} | ${'icon'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${'icon'} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${true} | ${true} | ${null} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${true} | ${false} | ${null} | ${false} | ${'group'} | ${'Avatar of Name, Active'}
${false} | ${false} | ${true} | ${'src'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'src'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'src'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${'icon'} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${true} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
${false} | ${false} | ${false} | ${null} | ${false} | ${'img'} | ${'Avatar of Name'}
`(
'Test accessibility of Avatar',
({withOnPress, withPresence, isPerson, avatarType, isTyping ,expectedLabel}) => {
checkAvatarAccessibility({withOnPress,withPresence,isPerson,avatarType,isTyping,expectedLabel});
`Test accessibility of Avatar when onPress is passed ? $withOnPress, presence is passed ? $withPresence, is person ? $isPerson,
avatar is $avatarType type, is typing ? $isTyping,containerRole should be $expectedRole , contaierLabel should be $expectedLabel`,
({withOnPress, withPresence, isPerson, avatarType, isTyping,expectedRole ,expectedLabel}) => {
checkAvatarAccessibility({withOnPress,withPresence,isPerson,avatarType,isTyping,expectedRole,expectedLabel});
}
);
});
});

24 changes: 12 additions & 12 deletions src/components/Avatar/Avatar.unit.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ exports[`Avatar snapshot should match snapshot 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand All @@ -36,7 +36,7 @@ exports[`Avatar snapshot should match snapshot with aria-label 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
/>
</Avatar>
`;
Expand Down Expand Up @@ -122,7 +122,7 @@ exports[`Avatar snapshot should match snapshot with icon 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Icon
className="md-avatar-wrapper-children md-avatar-icon-wrapper"
Expand Down Expand Up @@ -162,7 +162,7 @@ exports[`Avatar snapshot should match snapshot with iconOnHover 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<div
className="md-avatar-wrapper-children md-avatar-icon-on-hover-wrapper"
Expand Down Expand Up @@ -206,7 +206,7 @@ exports[`Avatar snapshot should match snapshot with initials 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -235,7 +235,7 @@ exports[`Avatar snapshot should match snapshot with isTyping and typingLabel 1`]
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -321,7 +321,7 @@ exports[`Avatar snapshot should match snapshot with mainLabel 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
/>
</button>
</FocusRing>
Expand Down Expand Up @@ -368,7 +368,7 @@ exports[`Avatar snapshot should match snapshot with onPress 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -403,7 +403,7 @@ exports[`Avatar snapshot should match snapshot with presence and presenceLabel 1
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -1368,7 +1368,7 @@ exports[`Avatar snapshot should match snapshot with size 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={124}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -1396,7 +1396,7 @@ exports[`Avatar snapshot should match snapshot with src & title 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down Expand Up @@ -1431,7 +1431,7 @@ exports[`Avatar snapshot should match snapshot with type 1`] = `
className="md-avatar-wrapper"
data-color="default"
data-size={24}
role="group"
role="img"
>
<Initials
className="md-avatar-wrapper-children"
Expand Down
Loading

0 comments on commit 083b349

Please sign in to comment.