Skip to content

Commit ca92c4b

Browse files
authored
fix(avatars): status ring styling and accessibility (#2022)
1 parent 220a8ef commit ca92c4b

File tree

5 files changed

+132
-21
lines changed

5 files changed

+132
-21
lines changed

package-lock.json

Lines changed: 108 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/avatars/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"sideEffects": false,
2222
"types": "dist/typings/index.d.ts",
2323
"dependencies": {
24+
"@zendeskgarden/react-typography": "^9.7.0",
2425
"polished": "^4.3.1",
2526
"prop-types": "^15.5.7"
2627
},

packages/avatars/src/elements/Avatar.spec.tsx

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ describe('Avatar', () => {
3434
</Avatar>
3535
);
3636

37-
expect(getByText(badge)).not.toBeEmptyDOMElement();
37+
const element = getByText(badge);
38+
39+
expect(element).toHaveAttribute('aria-hidden');
3840
});
3941

4042
it('applies active styling to available status if provided with badge', () => {
@@ -75,49 +77,48 @@ describe('Avatar', () => {
7577
</Avatar>
7678
);
7779

78-
const statusIndicatorElement = getByText('2')?.parentElement;
80+
const element = getByText('status: active. 2 notifications');
7981

80-
expect(statusIndicatorElement).toHaveAttribute(
81-
'aria-label',
82-
'status: active. 2 notifications'
83-
);
82+
expect(element).toBeInTheDocument();
8483
});
8584

8685
it('renders with badge and with a provided status label', () => {
86+
const label = 'two notifications';
8787
const { getByText } = render(
88-
<Avatar badge="2" statusLabel="two notifications">
88+
<Avatar badge="2" statusLabel={label}>
8989
<img alt="" />
9090
</Avatar>
9191
);
9292

93-
const statusIndicatorElement = getByText('2')?.parentElement;
93+
const element = getByText(label);
9494

95-
expect(statusIndicatorElement).toHaveAttribute('aria-label', 'two notifications');
95+
expect(element).toBeInTheDocument();
9696
});
9797

98-
it('renders with status and applies default aria-label for available status', () => {
99-
const { getByLabelText } = render(
98+
it('renders with status and applies default label for available status', () => {
99+
const { getByText } = render(
100100
<Avatar status="available">
101101
<img alt="" />
102102
</Avatar>
103103
);
104104

105-
const statusIndicatorElement = getByLabelText('status: available');
105+
const element = getByText('status: available');
106106

107-
expect(statusIndicatorElement).toBeEmptyDOMElement();
107+
expect(element).toBeInTheDocument();
108108
});
109109

110-
it('renders with status and applies default aria-label for away status', () => {
111-
const { getByLabelText, container } = render(
110+
it('renders with status and applies default label for away status', () => {
111+
const { getByText, container } = render(
112112
<Avatar status="away">
113113
<img alt="" />
114114
</Avatar>
115115
);
116116

117-
const statusIndicatorElement = getByLabelText('status: away');
117+
const element = getByText('status: away');
118118
const statusIndicatorSVG = container.querySelector('svg');
119119

120-
expect(statusIndicatorElement).toContainElement(statusIndicatorSVG);
120+
expect(element).toBeInTheDocument();
121+
expect(statusIndicatorSVG).toBeInTheDocument();
121122
});
122123
});
123124

packages/avatars/src/elements/Avatar.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import React, { Children, forwardRef, useMemo } from 'react';
99
import PropTypes from 'prop-types';
1010
import { useText } from '@zendeskgarden/react-theming';
11+
import { Span } from '@zendeskgarden/react-typography';
1112
import ClockIcon12 from '@zendeskgarden/svg-icons/src/12/clock-stroke.svg';
1213
import ClockIcon16 from '@zendeskgarden/svg-icons/src/16/clock-stroke.svg';
1314
import ArrowLeftIcon12 from '@zendeskgarden/svg-icons/src/12/arrow-left-sm-stroke.svg';
@@ -59,7 +60,7 @@ const AvatarComponent = forwardRef<HTMLElement, IAvatarProps>(
5960
}, [computedStatus, badge]);
6061

6162
const shouldValidate = computedStatus !== undefined;
62-
const ariaLabel = useText(
63+
const label = useText(
6364
AvatarComponent,
6465
{ statusLabel },
6566
'statusLabel',
@@ -86,11 +87,11 @@ const AvatarComponent = forwardRef<HTMLElement, IAvatarProps>(
8687
$size={size}
8788
$type={computedStatus}
8889
$surfaceColor={surfaceColor}
89-
aria-label={ariaLabel}
9090
as="figcaption"
9191
>
92+
<Span hidden>{label}</Span>
9293
{computedStatus === 'active' ? (
93-
<span aria-hidden="true">{badge}</span>
94+
<span aria-hidden>{badge}</span>
9495
) : (
9596
<>
9697
{computedStatus === 'away' ? <ClockIcon data-icon-status={computedStatus} /> : null}

packages/avatars/src/styled/StyledAvatar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ const sizeStyles = (props: IStyledAvatarProps & ThemeProps<DefaultTheme>) => {
153153
height: ${size} !important; /* [1] */
154154
/* stylelint-enable declaration-no-important */
155155
156-
::before {
156+
&::before {
157157
box-shadow: ${boxShadow};
158158
}
159159

0 commit comments

Comments
 (0)