Skip to content

navigation in useRadioGroup using keyboard arrows break if there is another focusable element withing the group #2379

@Pustelto

Description

@Pustelto

🐛 Bug Report

Hi,

I had to create this pattern in one project: https://design-system.service.gov.uk/components/radios/conditional-reveal/index.html. But when I tried to navigate between the radios using arrow keys the focus was last and value of the radio group was set to null. This is because the getFocusableTreeWalker select any focusable element, even in this case it should really select only radio buttons.

🤔 Expected Behavior

After pressing arrow key, if the radio button is focused, I would expect the next radio to be selected and focused, even if there is some other focusable element. in between those two radio buttons.

😯 Current Behavior

Focus is removed from the radio group, because it is trying to focus non-radio element which is removed from the dom.

💁 Possible Solution

I have add another option to the getFocusableTreeWalker using patch-package. Which is a callback used to modify default selectors. Whatever is returned from this callback will be used as a new selector for tree walker.

export function getFocusableTreeWalker(root, opts, scope) {
  let selector = opts?.tabbable ? TABBABLE_ELEMENT_SELECTOR : FOCUSABLE_ELEMENT_SELECTOR;
  if (opts.selectorModifier) {
    selector = opts.selectorModifier(selector)
  }
  let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
    acceptNode(node) {
      ...


// Then in the useRadioGroup function in the onKeyDown method

let walker = getFocusableTreeWalker(e.currentTarget, {
      from: e.target,
      selectorModifier: function( selector ) { 
        return "input[type=radio]:not([disabled]):not([type=hidden]):not([hidden])" 
      }
    });

🔦 Context

This is one of the issues I have faced when trying to create conditional reveal from the example above. I had to use patch-package to make this work as intended. But I would like to be this fixed in the library.

💻 Code Sample

https://codesandbox.io/s/silly-violet-ow97m?file=/src/App.js:674-693

🌍 Your Environment

Software Version(s)
react-spectrum 3.4.1
Browser Chrome 93
Operating System macOS

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions