Skip to content

fix(a11y): announce read-only state of form components to screen readers#2

Open
it-rec wants to merge 27 commits into
mainfrom
claude/carbon-issue-22407-qesd41
Open

fix(a11y): announce read-only state of form components to screen readers#2
it-rec wants to merge 27 commits into
mainfrom
claude/carbon-issue-22407-qesd41

Conversation

@it-rec

@it-rec it-rec commented Jun 10, 2026

Copy link
Copy Markdown
Owner

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

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 it-rec force-pushed the claude/carbon-issue-22407-qesd41 branch from 9c4e182 to 9c74872 Compare June 10, 2026 06:13
it-rec and others added 26 commits June 19, 2026 06:05
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.
…em#22630)

* feat: add code connhect support for web components

* fix(web-components): update Code Connect snippets from review

* fix(web-components): align tooltip and toggle mappings

* chore: add tree-view issue note
…arbon-design-system#22632)

* chore(deps): bump github/codeql-action/analyze from 4.36.2 to 4.36.3

Bumps [github/codeql-action/analyze](https://github.com/github/codeql-action) from 4.36.2 to 4.36.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@8aad20d...54f647b)

---
updated-dependencies:
- dependency-name: github/codeql-action/analyze
  dependency-version: 4.36.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: bump github/codeql-action/init to fix mismatch

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: devadula-nandan <47176249+devadula-nandan@users.noreply.github.com>
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.
…-system#22509)

* feat(react): overflowmenu contextual layout token cov

* feat(wc): overflowmenu contextual layout token cov

* fix: missing layout--size class

* chore: cleanup

* test: update tests and snapshots

* chore: add test stories

* fix: remove stale size attribute when removed at runtime

* fix: clear stale size on menu body/items

* chore: remove test stories

* docs: add TODO comment
* fix(popover): set color for tab tip button

* chore: update copyright year

* chore: set color

---------

Co-authored-by: Heloise Lui <71858203+heloiselui@users.noreply.github.com>
…n-system#22657)

* fix(overflow-menu): preserve visible programmatic focus across browsers

* fix(overflow-menu): address review feedback

* fix(overflow-menu): include breadcrumb fallback focus styling
…rbon-design-system#22644)

* fix: flags scope merge issue

* docs: visualize feature flag scopes

* refactor: simplify

* chore: remove comment

* chore: clean up copyright year and comment

* Update packages/react/src/components/FeatureFlags/index.tsx

Co-authored-by: Adam Alston <aalston9@gmail.com>

* fix: re-attach js comment and hide stories

* chore: remove feature flags test story completly

---------

Co-authored-by: Adam Alston <aalston9@gmail.com>
…design-system#22275)

* fix(layout): update style modules to respect emit boundaries

* test(layout): cover utility emit boundaries

* fix(layout): emit web component size context classes

* fix(layout): restore layout context styles

---------

Co-authored-by: Heloise Lui <71858203+heloiselui@users.noreply.github.com>
Co-authored-by: sangeethababu9223 <58620134+sangeethababu9223@users.noreply.github.com>
Co-authored-by: Sangeetha Babu <sangeetha9223@gmail.com>
…arbon-design-system#22651)

* fix(header): return explicit boolean value for header panel expanded

* chore: remove the true value

* chore: add test case for header panel

* chore: fix copyright date

* chore: update test file name and simplify

* chore: update copyright year

---------

Co-authored-by: Heloise Lui <71858203+heloiselui@users.noreply.github.com>
…rbon-design-system#22681)

* chore(deps): bump github/codeql-action/init from 4.36.3 to 4.37.0

Bumps [github/codeql-action/init](https://github.com/github/codeql-action) from 4.36.3 to 4.37.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@54f647b...99df26d)

---
updated-dependencies:
- dependency-name: github/codeql-action/init
  dependency-version: 4.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore: upgrade github/codeql-action/analyze

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Anna Wen <54281166+annawen1@users.noreply.github.com>
…gn-system#22679)

Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.4.0 to 5.5.0.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@1bcf9fb...0f481fc)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 5.5.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[a11y]: SR does not announce readonly status of form elements

6 participants