javascriptnode.jsreactjstypescriptaccessibility

Tabindex is not focusing on the next element


I'm trying to tab between different radio button inputs using React/TypeScript. I can get the first radio button focused, but when I click tab, it focuses outside of the radio buttons. I tried using react-focus-trap but tab wouldn't focus on any input elements (I may have been using it incorrectly though).

Here is my component where I am setting the tab index on the components

RadioButton.tsx

import { useState } from "react";
import type { SurveyAnswer } from "./demographicssurvey";

interface RadioButtonAnswersProps {
  answers: SurveyAnswer[];
  updateCurrentAnswer: (val: string) => void;
  setDisabled: (val: boolean) => void;
}
export default function RadioButtonAnswers({
  answers,
  updateCurrentAnswer,
  setDisabled,
}: RadioButtonAnswersProps) {
  const [disabledInput, setDisabledInput] = useState("");
  const handleChange = (val: string) => {
    updateCurrentAnswer(val);
    setDisabled(false);
  };

  const radioBtn = (a: SurveyAnswer, index: number) => {
    console.log("Index is:", index)
    return (
        <label>
          <input
            autoFocus={index === 0}
            tabIndex={0}
            className="form-radio"
            type="radio"
            name="myRadio"
            value={a.answer}
            onFocus={(e) =>  {
              e.target.checked = true;
              handleChange((e.target as HTMLInputElement).value)
            }}
            onClick={(e) => handleChange((e.target as HTMLInputElement).value)}
            onChange={() => {
              setDisabledInput("");
              return;
            }}
          />
          <span className="mx-2">{a.answer}</span>
        </label>
    );
  };

  const radioBtnText = (a: SurveyAnswer, index: number) => {
    return (
        <label>
          <input
            autoFocus={index === 0}
            tabIndex={0}
            type="radio"
            className="form-radio"
            name="myRadio"
            value={a.answer}
            onFocus={(e) =>  {
              e.target.checked = true;
              handleChange((e.target as HTMLInputElement).value)
            }}
            onClick={() => setDisabledInput(a.answer)}
            onChange={() => {
              return;
            }}
          />
          <span className="mx-2">
            {a.answer}
            <input
              className="form-input rounded"
              tabIndex={0}
              type={"text"}
              disabled={disabledInput !== a.answer}
              onChange={(e) =>
                handleChange(a.answer + (e.target as HTMLInputElement).value)
              }
            ></input>
          </span>
        </label>
    );
  };
  return (
      <>
        {answers.map((a, index) => {
          return (
            <ul key={index}>
              {a.answerType === "option"
                ? radioBtn(a, index)
                : a.answerType === "optionText"
                ? radioBtnText(a, index)
                : null}
            </ul>
          );
        })}
      </>
  );
}

Any help is appreciated!


Solution

  • Navigating Radio buttons is like navigating a select:

    If you want to navigate your radio group by pressing tab, you will need to build your own radio buttons