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

Screen reader issues when trying to add a label to react select #5992

Open
legostud opened this issue Jan 10, 2025 · 0 comments
Open

Screen reader issues when trying to add a label to react select #5992

legostud opened this issue Jan 10, 2025 · 0 comments
Labels
issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet

Comments

@legostud
Copy link

I ran into issues trying to properly add an accessible label to the react-select element on my Form component.

I added react select without a label element and my Chrome aXe dev tools extension flagged it as missing a name (4.1.2).
image

The docs on your site say to wrap react select in a label element so I did that and now the Voice Over screen reader (MAC) is over announcing information that isn't helpful. aXe is now happy, but the user now has a worse experience than before.

image

To resolve this issue, I had to find the id value on react select's role="combobox" input and set the for value of the label element to use that value instead of wrapping your component in a label as instructed. Now Voice Over reads as expected.

image

I tried doing what I though would be the easiest approach by populate the id prop on react select, but that didn't place the id on the input and instead set it on a wrapping div, which wasn't helpful. Would it be possible to either pass a label value into react select to properly setup the label or to pass in an ID that can be added to the input so I can properly setup and external label?

For Reference, this is the final code that I'm using to resolve the issue.

import Select from "react-select";

const SelectApp = (props) => {
  const { options, name, label, placeholder } = props;
  const [selectId, setSelectId] = useState("");
  const inputRef = useRef();
  const selectRef = useRef();

  useEffect(() => {
    // get the id from the react-select input to meet WCAG requirements.
    // wrapping react-select in a label broke the screen reader.
    const input = selectRef.current?.querySelector("input");
    if (input?.id) {
      setSelectId(input.id);
    }
  }, [selectRef]);

  // store the selected value in an input so it can be submitted with the form.
  const handleChange = (selectedOption) => {
    inputRef.current.value = selectedOption.value;
  };

  return (
    <>
      <label className="select__label" htmlFor={selectId}>
        {label}
      </label>
      <input ref={inputRef} name={name} type="hidden" />
      <div className="select__input" ref={selectRef}>
        <Select
          options={options}
          onChange={handleChange}
          placeholder={placeholder}
        />
      </div>
    </>
  );
};
SelectApp.propTypes = propTypes;
export default SelectApp;
@legostud legostud added the issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet label Jan 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue/bug-unconfirmed Issues that describe a bug that hasn't been confirmed by a maintainer yet
Projects
None yet
Development

No branches or pull requests

1 participant