Skip to content

Commit 79b3311

Browse files
Zack Gomezkelset
authored andcommitted
Fix inability to remove 'Disabled' state from AccessibilityStates
Summary: D8842691 split AccessibilityTraits into multiple RN properties. However, the accessor code did not support REMOVING traits. This results in buttons that were disabled (AccessibilityTraits & NotEnabled === true) never being enabled. Fix the issue by making the split accessors properly mask in the bits, allowing you unset them without disturbing bits managed by the other accessor. NOTE: setting AccessibilityTraits and AccessibilityRole or AccessibilityStates will still result in bugs. Reviewed By: shergin Differential Revision: D9661970 fbshipit-source-id: 77d70dd0754f2eaf8cbf895bfc13757c697a76d8
1 parent 26b5a6e commit 79b3311

2 files changed

Lines changed: 14 additions & 2 deletions

File tree

Libraries/Components/View/ViewAccessibility.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ module.exports = {
8484
'radiobutton_checked',
8585
'radiobutton_unchecked',
8686
],
87+
// This must be kept in sync with the AccessibilityRolesMask in RCTViewManager.m
8788
AccessibilityRoles: [
8889
'none',
8990
'button',
@@ -97,5 +98,6 @@ module.exports = {
9798
'header',
9899
'summary',
99100
],
101+
// This must be kept in sync with the AccessibilityStatesMask in RCTViewManager.m
100102
AccessibilityStates: ['selected', 'disabled'],
101103
};

React/Views/RCTViewManager.m

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,22 @@ - (RCTShadowView *)shadowView
151151

152152
RCT_CUSTOM_VIEW_PROPERTY(accessibilityRole, UIAccessibilityTraits, RCTView)
153153
{
154-
view.reactAccessibilityElement.accessibilityTraits |= json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
154+
// This mask must be kept in sync with the AccessibilityRoles enum defined in ViewAccessibility.js
155+
const UIAccessibilityTraits AccessibilityRolesMask = UIAccessibilityTraitNone | UIAccessibilityTraitButton | UIAccessibilityTraitLink | UIAccessibilityTraitSearchField | UIAccessibilityTraitImage | UIAccessibilityTraitKeyboardKey | UIAccessibilityTraitStaticText | UIAccessibilityTraitAdjustable | UIAccessibilityTraitHeader | UIAccessibilityTraitSummaryElement;
156+
157+
UIAccessibilityTraits newTraits = json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
158+
UIAccessibilityTraits maskedTraits = newTraits & AccessibilityRolesMask;
159+
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityRolesMask) | maskedTraits;
155160
}
156161

157162
RCT_CUSTOM_VIEW_PROPERTY(accessibilityStates, UIAccessibilityTraits, RCTView)
158163
{
159-
view.reactAccessibilityElement.accessibilityTraits |= json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
164+
// This mask must be kept in sync with the AccessibilityStates enum defined in ViewAccessibility.js
165+
const UIAccessibilityTraits AccessibilityStatesMask = UIAccessibilityTraitNotEnabled | UIAccessibilityTraitSelected;
166+
167+
UIAccessibilityTraits newTraits = json ? [RCTConvert UIAccessibilityTraits:json] : defaultView.accessibilityTraits;
168+
UIAccessibilityTraits maskedTraits = newTraits & AccessibilityStatesMask;
169+
view.reactAccessibilityElement.accessibilityTraits = (view.reactAccessibilityElement.accessibilityTraits & ~AccessibilityStatesMask) | maskedTraits;
160170
}
161171

162172
RCT_CUSTOM_VIEW_PROPERTY(pointerEvents, RCTPointerEvents, RCTView)

0 commit comments

Comments
 (0)