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

[a11y]: NumberInput: use builtin increment/decrement pseudoelements? #18078

Open
2 tasks done
wkeese opened this issue Nov 15, 2024 · 0 comments
Open
2 tasks done

[a11y]: NumberInput: use builtin increment/decrement pseudoelements? #18078

wkeese opened this issue Nov 15, 2024 · 0 comments

Comments

@wkeese
Copy link
Contributor

wkeese commented Nov 15, 2024

Package

@carbon/react

Browser

Chrome

Operating System

MacOS

Package version

1.69.0

React version

18

Automated testing tool and ruleset

VoiceOver

Assistive technology

No response

Description

NumberInput explicitly renders the increment and decrement buttons using the <button> element.

<div class="cds--number__controls">
  <button aria-label="Decrement number" class="cds--number__control-btn down-icon" tabindex="-1" title="Decrement number" type="button">...</button>
  <div class="cds--number__rule-divider"></div>
  <button aria-label="Increment number" class="cds--number__control-btn up-icon" tabindex="-1" title="Increment number" type="button">../button>
  <div class="cds--number__rule-divider">
</div>

These buttons are useless to keyboard users since keyboard users can increment/decrement the value with the up and down arrow keys.

The buttons have tabindex=-1 so they aren't in the tab-navigation, but they still have various accessibility issues.

Acccessibility issues

(1) Ambiguity

If we have multiple NumberInput components they will essentially render like this:

<label for=p>Precision</label>
<input id=p>
<button>increment</button>
<button>decrement</button>
<label for=s>Scale</label>
<input id=s>
<button>increment</button>
<button>decrement</button>

I think a human can guess which inputs each button belongs to, but it's not entirely clear. It's also annoying to write unit tests if (for some reason) the unit tests wants to (for example) click the decrement button of the second NumberInput.

(2) VoiceOver

Although JAWS and NVDA will skip over the buttons, VoiceOver will not. This seems suboptimal for VoiceOver users that have no interest in those buttons.

Possible solutions

(3) How about setting aria-hidden around the buttons?

I don't think this works, it's problematic to have interactive controls inside an aria-hidden block.

(4) How about wrapping the whole thing in a <fieldset>?

<fieldset>
    <legend>Precision</legend>
    <label for=p>Precision</label>
    <input id=p>
    <button>increment</button>
    <button>decrement</button>
</fieldset>

I don't like that either, it's problematic because the label is repeated twice.

(5) Styling buttons

Therefore, my suggestion is to the browser's native buttons, but style them how carbon wants them, i.e. NumberInput simply becomes

<input type=number class=class="cds--number__input"/>

And then all the magic happens in cds--number__input.

See https://stackoverflow.com/questions/45396280/customizing-increment-arrows-on-input-of-type-number-using-css.

It sure looks possible.

WCAG 2.1 Violation

No response

Reproduction/example

https://react.carbondesignsystem.com/?path=/story/components-numberinput--default

Steps to reproduce

N/A

Suggested Severity

None

Code of Conduct

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

1 participant