Repository navigation
Backport macOS accessibility and TextInput fixes to 0.81-stable, with Paper validation #3135
Description
Summary
Backport the macOS accessibility and TextInput fixes from main (#3136) to 0.81-stable, and finish the Paper (old architecture) work that can't be done on main. main no longer builds the legacy architecture, so the Paper code paths in those commits are untested.
FluentUI React Native applies these fixes to react-native-macos 0.81.9 through a Yarn patch (added in microsoft/fluentui-react-native#4386). It can remove the patch once a 0.81 release contains them.
Commits to backport
Cherry-pick in order. Each commit builds on its own; the last one is optional.
| # | Commit | Change |
|---|---|---|
| 1 | 68644c74c3 |
RCTConvert: convert each array element with the ARIA role table |
| 2 | 533d408e74 |
Fabric: role from role / accessibilityRole, written to the accessibility element; legacy textbox mapping |
| 3 | deb87cffa6 |
Fabric: disabled, selected and expanded state on the accessibility element |
| 4 | 10be049e17 |
Read-only vs. disabled TextInput (single-line and multiline, Paper and Fabric) |
| 5 | 676c01f0c4 |
Fabric: one Tab stop per TextInput |
| 6 | a40ec92a3d |
Optional: recycled TextInputs keep their default role when the backing view is swapped |
Cherry-pick dry run against 0.81-stable (41bc5d5eb4)
- All native changes apply cleanly.
- Commits 2 and 3 conflict only in
packages/rn-tester/js/examples/Accessibility/AccessibilityExample.js. Resolve by adding the two macOS examples to the 0.81 version of the file.
Follow .ai/commands/backport.md: branch 0.81/user/jasonvmo/a11y-fixes, PR titles fix(0.81, macos): …. PRs to 0.81-stable also need a changeset (yarn change:check).
Paper work
These Paper paths changed but could not be exercised on main:
- Read-only: a single-line field with
editable={false}is reachable with Tab, its text can be selected and copied, typing is rejected, and it reports AXEnabled = YES. Theeditableprop reachesRCTUITextFieldthroughRCT_REMAP_VIEW_PROPERTY(editable, backedTextInputView.editable, BOOL). - Disabled: with
accessibilityState={{disabled: true}}, single-line and multiline fields are skipped by Tab, refuse click focus, and report AXEnabled = NO. Paper routes the prop through-[RCTBaseTextInputView reactAccessibilityElement]to the new-setAccessibilityState:overrides onRCTUITextFieldandRCTUITextView. - Prop removal: removing
accessibilityStateentirely, not just passing{disabled: false}, re-enables the field. This relies on the newnilhandling inRCT_CUSTOM_VIEW_PROPERTY(accessibilityState, …). - Wrapper focus:
RCTBaseTextInputViewalready returns NO fromcanBecomeKeyView. However,-[RCTView acceptsFirstResponder]returnsfocusable || super, and TextInput defaultsfocusableto true. Check whether clicking the wrapper outside the editor makes it first responder or sends an extra focus event. If it does, add theacceptsFirstResponderoverride that the Fabric component view now has. - Roles:
accessibilityRole="textbox"reports AXTextField through the new legacy mapping. - Tab stops: a row of three single-line fields, and a multiline field, each take one Tab press in each direction.
- Appearance: AppKit's disabled styling now applies to disabled fields instead of read-only ones. Check text and placeholder colors.
Fabric re-check on 0.81
Run the RNTester examples added by the commits on the new architecture:
- Accessibility: "Roles from role and accessibilityRole" and "Disabled, selected and expanded state".
- TextInput: "Read-only and disabled" and "Tab stops".
Commit 5 makes the RNTester-macOS window recalculate its key-view loop. Without that change, Tab doesn't move between React Native views in RNTester.
Downstream check
Before tagging the release, point FluentUI React Native at a local build and run yarn storybook smoke --macos --mode stories-and-tests and its --paper variant. Use the selectors components-*--*focus*, components-dropdown--*, components-menu*--* and native-modern-callout--*. With the patch these pass with zero skips: 19/19 shared focus, 8/8 Dropdown, 8/8 Menu and 16/16 Callout. The release should pass the same cases unpatched.
Activity