Skip to content

Commit

Permalink
Banner: Fix a11y issue by adding role=img to icons (#2142)
Browse files Browse the repository at this point in the history
## Summary:

- Banner: Fix a11y issue that caused that icons were not read by screen readers
properly.

- PhosphorIcon: Improved docs to explain how to use the `role` prop +
added unit tests.

Issue: XXX-XXXX

## Test plan:

1. Navigate to the Banner component in the docs and verify that the icons are read
by screen readers properly (e.g. includes `info` before reading the message).

http://localhost:6061/?path=/story/banner--default

2. Navigate to the PhosphorIcon component in the docs and verify that the `role`
prop is documented properly.

http://localhost:6061/?path=/docs/icon-phosphoricon--docs#announcing-the-icon-to-assistive-technology

Author: jandrade

Reviewers: jeresig

Required Reviewers:

Approved By: jeresig

Checks: ✅ Chromatic - Get results on regular PRs (ubuntu-latest, 16.x), ✅ codecov/project, ✅ Test (ubuntu-latest, 16.x, 2/2), ✅ Test (ubuntu-latest, 16.x, 1/2), ✅ Lint (ubuntu-latest, 16.x), ✅ Check build sizes (ubuntu-latest, 16.x), ✅ Chromatic - Build on regular PRs / chromatic (ubuntu-latest, 16.x), ✅ Publish npm snapshot (ubuntu-latest, 16.x), ⏭  Chromatic - Skip on Release PR (changesets), ✅ Check for .changeset entries for all changed files (ubuntu-latest, 16.x), ✅ gerald, ✅ Prime node_modules cache for primary configuration (ubuntu-latest, 16.x), ⏭  dependabot

Pull Request URL: #2142
  • Loading branch information
jandrade authored Dec 14, 2023
1 parent 56a896c commit 23ab9f8
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .changeset/perfect-chefs-lay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@khanacademy/wonder-blocks-banner": patch
"@khanacademy/wonder-blocks-icon": patch
---

Added `role="img"` docs to PhosphorIcon. Fixed a11y issue to banners by adding the img role to the icons in each banner"
3 changes: 3 additions & 0 deletions __docs__/wonder-blocks-icon/accessibility.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ import {IconMappings} from "./phosphor-icon.argtypes";
- Icons should go on the opposite side as left-to-right languages
for right-to-left languages.
- The icon may also need to be mirrored.
- If you are using `aria-label`, make sure to also use `role="img"` so that
screen readers know that the element is an image and not just decorative
text.

More information about all these points can be found in the
[References](#references) below.
Expand Down
4 changes: 3 additions & 1 deletion __docs__/wonder-blocks-icon/phosphor-icon.argtypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ export default {
},
},
role: {
description: "The role of this icon.",
description:
"The role of this icon. Make sure to use it when setting `aria-label`\n" +
"See: https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA24",
defaultValue: "img",
control: {
type: "text",
Expand Down
22 changes: 22 additions & 0 deletions __docs__/wonder-blocks-icon/phosphor-icon.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,25 @@ const styles = StyleSheet.create({
margin: tokens.spacing.xxxxSmall_2,
},
});

/**
* Icons are not announced by default, as they are usually decorative. However,
* if you want to announce the icon, you can pass an `aria-label` and
* `role="img"` props to the `PhosphorIcon` component.
*/
export const DescriptiveIcon: StoryComponentType = {
name: "Announcing the icon to assistive technology",
args: {
icon: IconMappings.magnifyingGlassBold,
size: "small",
role: "img",
"aria-label": "Search",
},
parameters: {
chromatic: {
// This story is not meant to be visually tested, so we disable
// snapshots.
disableSnapshot: true,
},
},
};
1 change: 1 addition & 0 deletions packages/wonder-blocks-banner/src/components/banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ const Banner = (props: Props): React.ReactElement => {
style={styles.icon}
aria-label={kind}
testId="banner-kind-icon"
role="img"
/>
<View style={styles.labelAndButtonsContainer}>
<View style={styles.labelContainer}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,24 @@ describe("PhosphorIcon", () => {
expect(ref.current).toBeInstanceOf(HTMLSpanElement);
});

it("applies role to icon", async () => {
// Arrange

// Act
render(<PhosphorIcon icon={Plus} role="img" />);

// Assert
expect(screen.getByRole("img")).toBeInTheDocument();
});

it("applies aria-label to icon", async () => {
// Arrange

// Act
render(
<PhosphorIcon
icon={Plus}
aria-label="something"
testId="phosphor-icon"
/>,
);
render(<PhosphorIcon icon={Plus} aria-label="something" role="img" />);

// Assert
expect(screen.getByTestId("phosphor-icon")).toHaveAttribute(
expect(screen.getByRole("img")).toHaveAttribute(
"aria-label",
"something",
);
Expand Down
11 changes: 9 additions & 2 deletions packages/wonder-blocks-icon/src/components/phosphor-icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,24 @@ type Props = Pick<AriaProps, "aria-hidden" | "aria-label" | "role"> & {
* Adds CSS classes to the Icon.
*/
className?: string;

/**
* Test ID used for e2e testing.
* The role of the icon.
* @see https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA24
*/
testId?: string;
role?: "img";

/**
* Size of the icon. One of `small` (16), `medium` (24), `large` (48), or
* `xlarge` (96). Defaults to `small`.
*/
size?: IconSize;

/**
* Test ID used for e2e testing.
*/
testId?: string;

/**
* The icon to display. This is a reference to the icon asset (imported as a
* static SVG file).
Expand Down

0 comments on commit 23ab9f8

Please sign in to comment.