Skip to content

Commit

Permalink
fix(loader): set role to status
Browse files Browse the repository at this point in the history
Updates the role of Loader to "status", as the role of "progressbar" failes WCAG 1.3.1

fix #6956
  • Loading branch information
nuria1110 committed Jan 23, 2025
1 parent 82596c2 commit 0407695
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/components/confirm/confirm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ test("should render disabled confirm button with Loader if isLoadingConfirm is s
);

expect(screen.queryByRole("button", { name: "Yes" })).not.toBeInTheDocument();
expect(screen.getByRole("progressbar", { name: "Loading" })).toBeVisible();
expect(screen.getByRole("status", { name: "Loading" })).toBeVisible();
expect(screen.getByTestId("confirm-button")).toBeDisabled();
});

Expand Down
2 changes: 1 addition & 1 deletion src/components/loader/loader.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const Loader = ({
return (
<StyledLoader
aria-label={ariaLabel || l.loader.loading()}
role="progressbar"
role="status"
{...tagComponent("loader", rest)}
{...filterStyledSystemMarginProps(rest)}
>
Expand Down
6 changes: 1 addition & 5 deletions src/components/loader/loader.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ This is an example of the large Loader component. The larger size is only used w
This example shows a `Loader` nested inside of a `Button` component. To ensure that the correct styling is applied to the `Loader` component when it is nested inside of the `Button` component,
please remember to pass the `isInsideButton` prop to the `Loader` component.

This example also demonstrates how to ensure that the `Loader` component is accessible when used inside of the `Button` component.
It is important to wrap the `Button` component in a `span` (use when elements are inline) or `div` (use when elements are in a block) tag and pass the `aria-live` attribute with the value of `polite`. This will ensure that the screen reader will reliabily announce the updates of the button to the user.

Please note that ARIA live regions provide a means for conveying dynamic updates to users who rely on assistive technologies like screen readers.
These updates in this case include changes to the button's content. By incorporating live regions permanently into the DOM, we can ensure that users are consistently informed of relevant changes as they occur.
Note that `Loader` has a role of "status", meaning it has an implicit `aria-live="polite"` and will be announced by screen readers.

<Canvas of={LoaderStories.InsideButton} />

Expand Down
18 changes: 8 additions & 10 deletions src/components/loader/loader.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,14 @@ export const InsideButton: Story = () => {
const buttonContent = isLoading ? <Loader isInsideButton /> : "Click me";
const ariaContent = isLoading ? "Loading" : "Click me";
return (
<span aria-live="polite">
<Button
m={2}
buttonType="primary"
aria-label={ariaContent}
onClick={handleButtonClick}
>
{buttonContent}
</Button>
</span>
<Button
m={2}
buttonType="primary"
aria-label={ariaContent}
onClick={handleButtonClick}
>
{buttonContent}
</Button>
);
};
InsideButton.storyName = "Inside Button";
10 changes: 4 additions & 6 deletions src/components/loader/loader.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ jest.mock("../../hooks/useMediaQuery", () => ({

testStyledSystemMargin(
(props) => <Loader {...props} />,
() => screen.getByRole("progressbar"),
() => screen.getByRole("status"),
);

test("when the user disallows animations or their preference cannot be determined, alternative loading text is rendered", () => {
render(<Loader />);

expect(screen.getByText("Loading")).toBeInTheDocument();
expect(screen.getByText("Loading")).toBeVisible();
});

describe("when the user allows animations", () => {
Expand All @@ -39,14 +39,12 @@ describe("when the user allows animations", () => {
test("root element has accessible name", () => {
render(<Loader />);

expect(screen.getByRole("progressbar")).toHaveAccessibleName("Loading");
expect(screen.getByRole("status")).toHaveAccessibleName("Loading");
});

test("when custom `aria-label` is passed, set accessible name to its value", () => {
render(<Loader aria-label="Still loading" />);

expect(screen.getByRole("progressbar")).toHaveAccessibleName(
"Still loading",
);
expect(screen.getByRole("status")).toHaveAccessibleName("Still loading");
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ describe("rendered content", () => {
</SelectListWithInput>,
);

expect(screen.getByRole("progressbar", { name: "Loading" })).toBeVisible();
expect(screen.getByRole("status", { name: "Loading" })).toBeVisible();
});

it("renders options in a table layout when multiColumn prop is true", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ beforeEach(() => {
test("when `loading` is true, the correct Loader styles are applied", () => {
render(<Switch onChange={() => {}} loading />);

const loaderElement = screen.getByRole("progressbar");
const loaderElement = screen.getByRole("status", { name: "Loading" });

expect(loaderElement).toBeVisible();
expect(loaderElement).toHaveStyle({
Expand Down
2 changes: 1 addition & 1 deletion src/components/switch/__internal__/switch-slider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ test("when `checked` is true, only one panel renders", () => {
test("when `loading` is true, Loader component renders in the first panel", () => {
render(<SwitchSlider loading />);

const loader = screen.getByRole("progressbar");
const loader = screen.getByRole("status", { name: "Loading" });

expect(loader).toBeVisible();
});
Expand Down
7 changes: 3 additions & 4 deletions src/components/switch/switch.pw.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,9 @@ test.describe("Prop tests for Switch component", () => {
if (boolVal) {
await expect(switchInput(page)).toBeDisabled();

await expect(page.getByRole("progressbar")).toHaveAttribute(
"data-component",
"loader",
);
await expect(
page.getByRole("status", { name: "Loading" }),
).toBeVisible();
} else {
await expect(switchInput(page)).not.toBeDisabled();
}
Expand Down

0 comments on commit 0407695

Please sign in to comment.