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

walkRadio walks through all radio buttons #1125

Closed
DaPaleta opened this issue May 7, 2023 · 1 comment
Closed

walkRadio walks through all radio buttons #1125

DaPaleta opened this issue May 7, 2023 · 1 comment
Labels
bug Something isn't working needs assessment This needs to be looked at by a team member

Comments

@DaPaleta
Copy link

DaPaleta commented May 7, 2023

Reproduction example

https://codesandbox.io/s/hungry-zeh-fpim30?file=/src/App.test.js

Prerequisites

  1. render a native HTML radio group
  2. await user.keyboard('{ArrowRight'})
  3. expect the next radio button to be the active element

Expected behavior

active element should be the next radio button. MDN guide, aria guide.
In addition, the behavior direction is wrong for up/down arrow keys, as specified in the aria guide from before.

Actual behavior

I debugged the code and it seems like the for loop is called over and over as long as there are members in the radio group, which is wrong. It should only be called once.

User-event version

14.4.3

Environment

in my environment I used:

"jsdom": "^21.1.1"
"@testing-library/user-event": "^14.4.3"
"jest": "^29.5.0"
"css.escape": "^1.5.1" // polyfill for window.CSS.escape used in walkRadio

But it seems to reproduce in the sandbox for older environments as well.

Additional context

solution:

export function walkRadio(
  instance: Instance,
  el: HTMLInputElement & {type: 'radio'},
  direction: -1 | 1,
) {
  const window = getWindow(el)
  const group = Array.from(
    el.ownerDocument.querySelectorAll<HTMLInputElement & {type: 'radio'}>(
      el.name
        ? `input[type="radio"][name="${window.CSS.escape(el.name)}"]`
        : `input[type="radio"][name=""], input[type="radio"]:not([name])`,
    ),
  )
  for (let i = group.findIndex(e => e === el) + direction; ; i += direction) {
    if (!group[i]) {
      i = direction > 0 ? 0 : group.length - 1
    }
    if (group[i] === el) {
      return
    }
    if (isDisabled(group[i])) {
      continue
    }

    focusElement(group[i])
    instance.dispatchUIEvent(group[i], 'click')
    return
  }
}
@DaPaleta DaPaleta added bug Something isn't working needs assessment This needs to be looked at by a team member labels May 7, 2023
@ph-fritsche
Copy link
Member

Duplicate of #1048

@ph-fritsche ph-fritsche marked this as a duplicate of #1048 May 11, 2023
@ph-fritsche ph-fritsche closed this as not planned Won't fix, can't repro, duplicate, stale May 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs assessment This needs to be looked at by a team member
Projects
None yet
Development

No branches or pull requests

2 participants