Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update accessible roles for v5 #1031

Merged
merged 14 commits into from
Sep 20, 2023
Merged

Update accessible roles for v5 #1031

merged 14 commits into from
Sep 20, 2023

Conversation

clarkgunn
Copy link

@clarkgunn clarkgunn commented Sep 14, 2023

Description

Adjusts roles and attributes to better align with the WCAG Aria Authoring Practices Guide https://www.w3.org/WAI/ARIA/apg/patterns/carousel

  • New tabbed prop determines whether roles should follow the Basic Carousel or Tabbed Carousel requirements.
  • New landmark prop determines whether role should be a region landmark or have role group. Role and label have been moved from the slider frame to the parent carousel element so controls are contained within the label and role. Landmark regions should be intentional, so the default value is set to false.
  • New carouselId prop gives the carousel frame an id attribute which can be uniquely targeted by controls where there might be multiple carousels on a page. This could be replaced internally with useId with React 18.
  • Default frameAriaLabel has been changed to a slightly more useful 'Slider', the role description of 'carousel' will already be announced
  • Default pagination dots have been given the role tab, and aria-controls targeting their slide.
  • Pagination dots parent has been given the role tablist. As tabs need to be the immediate child of tablist, and since tablist already has list semantics, ul and li have been removed. This should resolve Attributes do not match their roles on carousel dots #1001 and the issue raised in Testing accessibility with jest-axe #803 regarding aria-selected.
  • When tabbed is true, slides will have the role tabpanel indicating they are the target of the tab, otherwise they will have the role group and a description of slide.
  • When tabbed is false, default pagination dots will not be rendered.
  • Default next and previous buttons now target the slider frame with aria-controls.

Adds dev dependencies: jest-axe, @types/jest-axe

Fixes #1001

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

These changes will impact the roles and attributes when default props are used. I believe this will improve accessibility but may be considered a breaking change.

How Has This Been Tested?

New jest and cypress tests were added. Existing cypress tests needed wait logic to pass, akin to this change 1f7f020

Cypress and Jest tests and Lighthouse accessibility report should all pass. Attributes and roles can be verified in devtools.

A tabbed carousel with chrome devtools displaying accessible roles and attributes.

An untabbed region landmark carousel with chrome devtools displaying accessible roles and attributes.

Checklist

  • My code follows the style guidelines of this project (I have run pnpm run lint)
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes (I have run pnpm run test:ci-with-server/pnpm run test)
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have recorded any user-facing fixes or changes with pnpm changeset.
  • My changes generate no new warnings
  • Any dependent changes have been merged and published in downstream modules

@vercel
Copy link

vercel bot commented Sep 14, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nuka-carousel-website ❌ Failed (Inspect) Sep 14, 2023 6:58pm

@clarkgunn clarkgunn marked this pull request as draft September 14, 2023 18:50
});

const carouselFrame = screen.getByRole('region');
const sliderFrame = screen.getByTestId(`${carouselId}-slider-frame`);
Copy link
Author

@clarkgunn clarkgunn Sep 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The region role is now applied to the whole carousel, this ensures the same slider frame element is being selected.

/**
* Unique id attribute for the carousel which may be referenced by aria attributes.
*/
carouselId: string;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with carouseld to disambiguate between id attributes and props on other elements.

/**
* Whether tab pagination is used to set appropriate roles for slides.
*/
tabbed: boolean;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabbed doesn't exactly align with the "pagination" and "dots" verbiage currently used, but it aligns with WCAG terminology.

@clarkgunn clarkgunn marked this pull request as ready for review September 14, 2023 19:12
@carloskelly13 carloskelly13 changed the base branch from main to 6 September 14, 2023 19:55
@carloskelly13 carloskelly13 changed the base branch from 6 to 5 September 14, 2023 19:56
<div
className={pagingDotsContainerClassName}
style={listStyles}
aria-label="Choose slide to display."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we let this be customizable with this string as default? (maybe this is more for an eventual port of this for v6 and not this specific use case)

Copy link
Contributor

@carloskelly13 carloskelly13 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for these improvements and getting this more inline. This will be also great to forward-port to v6 as well.

I'm not worried about the failed Vercel deployment on v5 since those docs are decommissioned, nor the Cypress tests on v5 since we knew those were broken in CI.

@clarkgunn clarkgunn merged commit 7945466 into 5 Sep 20, 2023
1 check passed
@clarkgunn clarkgunn deleted the task/roles branch September 20, 2023 23:40
@github-actions github-actions bot mentioned this pull request Sep 21, 2023
carloskelly13 added a commit that referenced this pull request Nov 2, 2023
* Migrate accessibility roles from v5 to v6

* Fix storybook configuration

* Fix existing Cypress tests

* Add query param support to demo used by cypress

* Fix serializing params for tests.

* Update demos.tsx

* Fix auto install peers

* Update cypress.config.ts

* Update carousel.test.tsx

* Add axe test violation checker for a carousel with control callbacks

* Add changeset

* Switch to major bump for new a11y props.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Attributes do not match their roles on carousel dots
2 participants