No ability to set aria-label to option
Discussed in https://github.com/JedWatson/react-select/discussions/5557
Originally posted by mellis481 February 14, 2023
It's possible to set an aria-label (or use aria-labelledby) on an HTML select option, but that doesn't not appear to be possible for an option in react-select. I've tried replacing the Option component as well as using the formatOptionLabel prop, but neither work. In fact, if I manually set an aria-label on all option nodes, the label is never announced by a screen reader.
An example use-case is if I want a label to visually appear as "= (Equals)" or "- (Subtract)", but want to set an aria-label so a screen reader won't read out "equals equals" or "minus subtract" respectively.
I have this problem with the same use case but with "!= (not equals)".
"!=" is announced as "equal" in the screen reader, and I tried hard to fix this problem, but it is not an easy solution. Overriding the Option component will not work because the focus logic/screen reader is managed by the LiveRegion.
My research so far:
React select use getOptionLabel to generate the label inside the LiveRegion
And then uses that label in the message.onFocus that builds the option part of the message the screen reader uses.
It may be possible to override the onFocus, but I didn't have time to follow that path.
Anyway, it would be easier if we could change this line:
https://github.com/JedWatson/react-select/blob/master/packages/react-select/src/components/LiveRegion.tsx#L124
from
label: getOptionLabel(focused),
to
label: focused.ariaLabel || getOptionLabel(focused),
Allowing consumers to set the aria label of each option if needed
I found a pretty effective workaround if anyone is having the same issue, you can use
getOptionLabel for the aria-label and then override what is visible with formatOptionLabel
something like this:
const getOptionLabel = (option: Option): string => option.ariaLabel;
const formatOptionLabel = (option: Option): string => option.label;
....
<Select
...
getOptionLabel={getOptionLabel}
formatOptionLabel={formatOptionLabel}
...
/>