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

@W-12627096@ Improve accessibility of variation attribute swatches #1587

Merged
merged 22 commits into from
Dec 18, 2023

Conversation

wjhsf
Copy link
Contributor

@wjhsf wjhsf commented Nov 30, 2023

Description

The implementation of the swatches is weird. It's buttons that act like links that act like radio inputs. Ideally, I would have liked to refactor this to use native radio inputs, because that would be simpler and more semantically correct. However, I couldn't get our current logic ("selected value" derived from the URL) to work nicely with Chakra's radio hooks/components (which, btw, are not particularly accessible!), so I gave up on that approach and just added missing accessibility features to the existing solution. Namely, I made tab navigation skip non-selected radio buttons and added the ability to select options using the arrow keys (see native behavior here). This seems to be as close to the native behavior as we can reasonably get, without doing a complete refactor of the component.

I also pulled the component out into a new file, because the indentation was getting excessive.

Types of Changes

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Breaking change (could cause existing functionality to not work as expected)
  • Other changes (non-breaking changes that does not fit any of the above)

Breaking changes include:

  • Removing a public function or component or prop
  • Adding a required argument to a function
  • Changing the data type of a function parameter or return value
  • Adding a new peer dependency to package.json

Changes

  • (change1)

How to Test-Drive This PR

  • Start dev server
  • Visit a product with variants
  • Tab through the page
  • When on the radio buttons, use the arrow keys to change the selection
  • Do a little dance
  • Use VoiceOver to validate that each variation attribute is read out like a native radio group

Checklists

General

  • Changes are covered by test cases
  • CHANGELOG.md updated with a short description of changes (not required for documentation updates)

Accessibility Compliance

You must check off all items in one of the follow two lists:

  • There are no changes to UI

or...

Localization

  • Changes include a UI text update in the Retail React App (which requires translation)

@wjhsf wjhsf requested a review from a team as a code owner November 30, 2023 21:23
wjhsf and others added 2 commits November 30, 2023 16:25
Signed-off-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
@wjhsf wjhsf enabled auto-merge (squash) November 30, 2023 21:43
onKeyDown={onKeyDown}
// To mimic the behavior of native radio inputs, only the selected input should be
// tabbable. (The rest are selectable via arrow keys.)
tabindex={selected ? 0 : -1}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Aside: the native behavior fields awkward in terms of accessibility since the non-selected options are not tabable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It makes sense if you think of the focused component as the radio group, rather than the individual radio button. Compare with a dropdown, where tab moves focus on/off the <select>, while arrow keys are how you choose an <option>.

bfeister
bfeister previously approved these changes Dec 4, 2023
const intl = useIntl()
const swatches = values.map(({href, name, image, value, orderable}) => {
/** Mimic the behavior of native radio inputs by using arrow keys to select prev/next value. */
const onKeyDown = (evt) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

why don't we put this as a prop for the Swatch-group component letting user to choose to enable/disable this behavior? if we have it here, it looks like it is only being used by ProductView

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One goal of this PR is to update the SwatchGroup component so that it does not modify its children. (i.e. it just renders {children} without changing the props.)

My solution here is definitely not the proper React solution, but I'm not sure the best way to implement this. The two main constraints are:

  1. (as mentioned) SwatchGroup renders its children without modification
  2. Using arrow keys when a swatch is focused changes the selected swatch.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Should this be the designed behavior for SwatchGroup? For example, if we have to use SwatchGroup somewhere else, using SwatchGroup would create them same accessibility issue, right? 🤔 .

Should we consider rewrite SwatchGroup to support accessibility instead of creating a "Wrapped" component like this one to patch the issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. I've moved the logic back into the Swatch and deleted the wrapper component.

@@ -108,7 +110,7 @@ describe('Swatch Component', () => {
const history = createMemoryHistory()
history.push('/en-GB/swatch-example?color=JJ2XNXX')

render(
renderWithProviders(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do we need to use renderWithProviders? I think it was intentional to not use the it since there is not need to render other providers to test this component.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Test fails without the providers. With these changes it needs the IntlProvider.

@alexvuong
Copy link
Collaborator

@wjhsf I checked out the changes localhost, it seems like the variants are not tablable, and when non variant is selected, using arrow keys are also not working, it will scroll the page. It only works when I use my mouse to click on the selection, then i can use arrow keys to move the variant selection. This seems like less accessible then before imo because I have to use my mouse to locate the variant buttons before I can use the arrow keys

@wjhsf
Copy link
Contributor Author

wjhsf commented Dec 7, 2023

@wjhsf I checked out the changes localhost, it seems like the variants are not tablable, and when non variant is selected, using arrow keys are also not working, it will scroll the page. It only works when I use my mouse to click on the selection, then i can use arrow keys to move the variant selection. This seems like less accessible then before imo because I have to use my mouse to locate the variant buttons before I can use the arrow keys

Is that the case when viewing this product? I can tab / arrow just fine... 🤔

@alexvuong
Copy link
Collaborator

@wjhsf that is when a variant has been selected, your url has pid, when you navigate from PLP to PDP, there is not variant select yet, so it is impossible to select the variant on that screen unless you use mouse. It was tablable on previous implementation

@wjhsf
Copy link
Contributor Author

wjhsf commented Dec 8, 2023

@wjhsf that is when a variant has been selected, your url has pid, when you navigate from PLP to PDP, there is not variant select yet, so it is impossible to select the variant on that screen unless you use mouse. It was tablable on previous implementation

Thanks for catching that! I've pushed a fix.

@wjhsf wjhsf requested a review from alexvuong December 8, 2023 17:14
@joeluong-sfcc
Copy link
Collaborator

Took a look at the associated ticket (W-12627096) and there's a recommended fix to add role="switch" to the size button filters on the PLP, is there a reason why that change wasn't included?

joeluong-sfcc
joeluong-sfcc previously approved these changes Dec 11, 2023
Signed-off-by: Will Harney <62956339+wjhsf@users.noreply.github.com>
Copy link
Collaborator

@adamraya adamraya left a comment

Choose a reason for hiding this comment

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

@wjhsf Looking at the screenshot linked in the ticket seems that the a11y issue is related to the size refinements buttons of the PLP not having the role HTML attribute.

Why are we not making changes to that file to include therole="switch" attribute?

@wjhsf
Copy link
Contributor Author

wjhsf commented Dec 15, 2023

@wjhsf Looking at the screenshot linked in the ticket seems that the a11y issue is related to the size refinements buttons of the PLP not having the role HTML attribute.

Why are we not making changes to that file to include therole="switch" attribute?

Because I accidentally improved the accessibility of the wrong swatches. 🤦 This PR improves the accessibility of an area unrelated to the ticket.

The root issue of the ticket is that we use buttons to select filters, but don't have any way for a screen reader to tell the user "this filter is not selected; click this button to add it" or "this filter is selected; click this button to remove it". I addressed that issue in #1607 (which is linked to a different ticket that I was working on that touches the same area). My fix is a bit different, it changes the labels rather than updating the ARIA attributes, but it achieves the same goal.

Copy link
Collaborator

@adamraya adamraya left a comment

Choose a reason for hiding this comment

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

The changes look good to me. I verified that now we can switch swatches back and forth using the keyboard arrow keys.

@wjhsf wjhsf merged commit 4815a62 into develop Dec 18, 2023
28 checks passed
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.

None yet

5 participants