fix(a11y): announce read-only state of form components to screen readers - #2
Open
it-rec wants to merge 19 commits into
Open
fix(a11y): announce read-only state of form components to screen readers#2it-rec wants to merge 19 commits into
it-rec wants to merge 19 commits into
Conversation
Form components previously did not communicate their read-only state to assistive technology, or did so using poorly-supported `aria-readonly` or misapplied `aria-disabled` (which announced editable fields as "disabled"). This violated WCAG 2.1 SC 4.1.2 (Name, Role, Value). Each affected component now renders a visually-hidden "Read only" description that is referenced from the focusable control via `aria-describedby`, providing a reliable, cross-screen-reader announcement. Misapplied `aria-disabled` on read-only Dropdown, MultiSelect and Checkbox group controls is replaced so disabled is only announced for genuinely disabled controls. `aria-readonly` is kept only on roles that support it. Covers React and Web Components packages: Checkbox, CheckboxGroup, Dropdown, MultiSelect, FilterableMultiSelect, NumberInput, RadioButton, RadioButtonGroup, Select, Slider, Toggle (and fluid variants, which inherit the behavior). Fixes carbon-design-system#22407
it-rec
force-pushed
the
claude/carbon-issue-22407-qesd41
branch
from
June 10, 2026 06:13
9c4e182 to
9c74872
Compare
Address review feedback: `aria-disabled=${disabled}` serialized the
boolean `false` to the string "false", rendering `aria-disabled="false"`
in the common (enabled) case. Use `ifDefined` so the attribute is
omitted unless the control is genuinely disabled, matching the
`aria-readonly`/`aria-describedby` pattern used elsewhere in this change.
Address Codecov patch-coverage gaps for this change: - slider: add tests for the range (two-handle) and hidden-text-input (tooltip) thumb render paths so the readonly aria-readonly/ aria-describedby attributes on all four thumbs are exercised. - multi-select: assert the clear-selection button gets aria-disabled when the component is disabled, covering that branch.
Address review feedback (adamalston): - CheckboxGroup: drop the fieldset-level "Read only" description and its aria-describedby entry. Each child Checkbox already announces read-only, so the group node caused a duplicate announcement. - RadioButtonGroup: propagate the group's readOnly to each child RadioButton (unless the child sets it), so the announcement lands on the focusable radio inputs, and remove the now-redundant fieldset-level description. aria-readonly stays on the fieldset for group semantics.
Address review feedback (adamalston): the visually-hidden "Read only" announcement was hardcoded. Make it translatable following Carbon's i18n guidance. React: each affected component now exposes translateWithId with a carbon.<component>.read-only message id defaulting to "Read only" (Checkbox, Toggle, RadioButton, Select gain the translateWithId API; NumberInput and Slider extend their existing translation maps; Dropdown, MultiSelect and FilterableMultiSelect widen their translateWithId key union and fall back to the default). Web Components: each affected component exposes a read-only-text attribute / readOnlyText property defaulting to "Read only". Adds unit tests asserting a custom translation overrides the default.
The NumberInput test helper throws on unknown message ids; add the new carbon.number-input.read-only id so readOnly renders that pass a custom translateWithId no longer throw.
Address review feedback (adamalston):
- Checkbox: the input's aria-describedby now includes the helper text id
(when shown) alongside the read-only announcement, so a read-only
Checkbox still exposes its helper text to screen readers. Matches the
existing NumberInput behavior.
- CheckboxGroup: replace the cx({ [helperId as string]: ... }) pattern
(which relied on cx dropping a falsy computed key and used an incorrect
type assertion) with a plain conditional string.
- MultiSelect/FilterableMultiSelect: drop the same helperId as string
assertion; pass the ids to cx as string arguments instead.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Form components previously did not communicate their read-only state to
assistive technology, or did so using poorly-supported
aria-readonlyor misapplied
aria-disabled(which announced editable fields as"disabled"). This violated WCAG 2.1 SC 4.1.2 (Name, Role, Value).
Each affected component now renders a visually-hidden "Read only"
description that is referenced from the focusable control via
aria-describedby, providing a reliable, cross-screen-readerannouncement. Misapplied
aria-disabledon read-only Dropdown,MultiSelect and Checkbox group controls is replaced so disabled is only
announced for genuinely disabled controls.
aria-readonlyis kept onlyon roles that support it.
Covers React and Web Components packages:
Checkbox, CheckboxGroup, Dropdown, MultiSelect, FilterableMultiSelect,
NumberInput, RadioButton, RadioButtonGroup, Select, Slider, Toggle
(and fluid variants, which inherit the behavior).
Fixes carbon-design-system#22407