react-select icon indicating copy to clipboard operation
react-select copied to clipboard

No ability to set aria-label to option

Open mellis481 opened this issue 2 years ago • 2 comments

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.

mellis481 avatar Feb 14 '23 18:02 mellis481

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

facupedrazzini avatar Mar 26 '24 00:03 facupedrazzini

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}
    ...
/>

facupedrazzini avatar Mar 27 '24 19:03 facupedrazzini