Skip to content

Reuse TouchableHighlight accessibility state without ARIA overrides - #59807

Open
javache wants to merge 2 commits into
react:mainfrom
javache:export-D129885143
Open

javache wants to merge 2 commits into
react:mainfrom
javache:export-D129885143

Conversation

@javache

@javache javache commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Summary:
Use the supplied accessibilityState as the default and only build a new state object when an ARIA state prop overrides it. This avoids reconstructing a sparse state object with extra undefined fields when no ARIA override is supplied. ARIA precedence and the explicit disabled override are unchanged.

Refresh the affected snapshots and assert that the button keeps its empty accessibility state.

Changelog: [Internal]

Differential Revision: D129885143

faciledictu and others added 2 commits November 5, 2026 02:38
…react#59378)

Summary:
Part of react#59377.

`Touchable*` build their host view props from a fixed list, and some props they accept in their types never reach it:

- `role`: none of `TouchableOpacity`, `TouchableHighlight`, `TouchableNativeFeedback`, `TouchableWithoutFeedback` passes it, so `<TouchableOpacity role="button">` has no role while `accessibilityRole="button"` works.
- `TouchableWithoutFeedback` drops `aria-label`.
- `TouchableHighlight` drops `aria-busy`, `aria-checked`, `aria-disabled`, `aria-expanded` and `aria-selected`; the other three already map them.

This change passes `role` from all four, maps `aria-label` in `TouchableWithoutFeedback` (it wins over `accessibilityLabel`, as in `View`, and the child keeps its own label when neither is set) and maps the state props in `TouchableHighlight` the same way `TouchableOpacity` does. `aria-labelledby` is left to react#58173.

The shared `rolePropSuite` now also runs for `TouchableNativeFeedback` and `TouchableWithoutFeedback`; before, it ran only for `Text`. It cannot run for `TouchableOpacity` and `TouchableHighlight`: Fantom reads the debug props of a view, and `AccessibilityProps::getDebugProps` does not include `role`, so `role` on their host view is checked on a device instead (pairs G / H of the reproducer).

## Changelog:

[GENERAL] [FIXED] - `role` on `Touchable*`, `aria-label` on `TouchableWithoutFeedback` and `aria-*` state props on `TouchableHighlight` reach the native view

Pull Request resolved: react#59378

Test Plan:
- `yarn fantom packages/react-native/Libraries/Components/Touchable`: 4 suites, 272 tests passed. (Locally with `CXXFLAGS=-Wno-deprecated-literal-operator`: Xcode 27.1 clang rejects the `operator "" _json` syntax of the bundled nlohmann_json 3.11.2 under `-Werror`; unrelated to this change.)
- `yarn flow-check`: no errors. `yarn eslint` on the changed files: no warnings.
- On a device: the reproducer https://github.com/faciledictu/rn-aria-props-repro, pairs G–L. Before: on Android 17, G is `android.view.ViewGroup`, I's `content-desc` is the child's "×", K has no `checked`; on iOS 27, G has no Button trait, I's label is "×", K's value has no "checked". After, on iOS 27: G has the Button trait, I's label is "Close I", K's value is "checkbox, checked". After, on Android 17: G is `android.widget.Button`, I's `content-desc` is "Close I", K is `checkable="true" checked="true"`. Each matches its `accessibility*` control (H, J, L).
- Snapshot refresh (2026-11-05): `js1 test --runInBand --watch=false --runTestsByPath` on `MobileHomeBAMFilterBar`, `MobileHomeBAMUrgencyPillter`, `TWTabPager`, `OCReferralsSurface` and `ActivityLogClearButton`: 5 suites, 25 tests and 17 snapshots passed after regenerating 14 snapshots. `TouchableHighlight.js` is unchanged from the original imported version.
- `arc lint -a`: no lint issues.

Differential Revision: D129326374

Pulled By: javache
Summary:
Use the supplied `accessibilityState` as the default and only build a new state object when an ARIA state prop overrides it. This avoids reconstructing a sparse state object with extra undefined fields when no ARIA override is supplied. ARIA precedence and the explicit `disabled` override are unchanged.

Refresh the affected snapshots and assert that the button keeps its empty accessibility state.

Changelog: [Internal]

Differential Revision: D129885143
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Nov 5, 2026
@facebook-github-tools facebook-github-tools Bot added p: Facebook Partner: Facebook Partner labels Nov 5, 2026
@meta-codesync

meta-codesync Bot commented Nov 5, 2026

Copy link
Copy Markdown

@javache has exported this pull request. If you are a Meta employee, you can view the originating Diff in D129885143.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants