Uh oh!
There was an error while loading. Please reload this page.
New Accessibility states API. - #24608
Conversation
analysis-bot
left a comment
There was a problem hiding this comment.
Code analysis results:
eslintfound some issues. Runyarn lint --fixto automatically fix problems.
There was a problem hiding this comment.
dot-notation: ["enabled"] is better written in dot notation.
Generated by 🚫 dangerJS against 780d6f51c50e7dc771cfa5cba37eaac81d565e39 |
necolas
commented
Apr 25, 2019
For context, this is a change I proposed here to provide an API that works for platforms where attributes must be present on host nodes to communicate their purpose to the native accessibility system |
necolas
left a comment
There was a problem hiding this comment.
This might need to support but deprecate the old API to give people time to migrate
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
marcmulcahy
commented
Apr 25, 2019
@necolas Any thoughts about how to deprecate the older API, while strongly encouraging developers to move to the new one? |
necolas
commented
Apr 25, 2019
Hopefully someone from RN Core will be able to advise |
cpojer
commented
Apr 25, 2019
Ideally we make this a non-breaking change for now by supporting both arrays or objects for a while, then we’ll add a warning in the release after, and then release a codemod (I can help with that) and then remove it. |
marcmulcahy
commented
May 3, 2019
@cpojer Not sure how to allow the native code to accept both an array of strings as well as an object. Any ideas? |
cpojer
commented
May 7, 2019
Unfortunately we can't make a breaking change like that in a single pull request. We could wrap |
cpojer
commented
May 9, 2019
@marcmulcahy do you have any idea for a new prop that we could introduce so that we could deprecate the existing one? I know this is unfortunate but it seems like the only way. If not, please close this PR. |
marcmulcahy
commented
May 9, 2019
@cpojer I suppose we could simply add a new prop called something like accessibilityStates2 that's an object instead of an array of strings. Switch all the RNTester samples and components to use accessibilityStates2, and then eventually deprecate accessibilityStates, or rename accessibilityStates2 to accessibilityStates. I do think this object-based API is much clearer, in that the component author must enumerate the states that "matter", and it makes much clearer how states are related to each other (expanded/collapsed, checked/unchecked, etc.). I'm also happy to close the PR if this isn't something we want to tackle ATM. Let me know what FB prefers to do. |
cpojer
commented
May 9, 2019
Alright, yeah I think we can do this. Can you change this PR to do the following:
In a month from now (sorry, this is some fb internal issue we have to deal with) we can then change how accessibilityStates works as long as we don't have internal users for it any longer. A month after that we can bring back the accessibilityStates prop with the new API and kill the deprecatedAccessibilityStates API. I'm sorry for this slow multi process step but I think it's worth doing it if you are up for it :) |
cpojer
commented
May 9, 2019
Alternatively, if we can think of a better name than
What would be a reasonable name for a new prop? |
|
cpojer
commented
May 9, 2019
I think that’s a great idea. Let’s do it! |
marcmulcahy
commented
May 22, 2019
As we discussed, this version moves the new API to a new property called "accessibilityState" and leaves "accessibilityStates" in tact. To verify that the existing prop was still working, I applied all the patches which add the new property, and left RNTester unchanged, and verified that RNTester behaves as before on both Android and iOS. I then modified RNTester to use "accessibilityState" instead of "accessibilityStates" and re-tested. |
necolas
commented
May 23, 2019
Looks good to me |
cpojer
left a comment
There was a problem hiding this comment.
That's fantastic. Thank you so much @marcmulcahy and I'm sorry for putting you through so much pain with this one but I really appreciate you were sticking with us :)
I made a few small inline reverts to ensure the current props keep working at FB during the migration phase. Once this PR is landed, do you mind sending a PR that removes accessibilityStates altogether? I can merge that one (in about a month from now) and then we'll be in a good state again :)
…t of strings contained in accessibilityStates with a more semantically rich object.
facebook-github-bot
left a comment
There was a problem hiding this comment.
@cpojer is landing this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
pull-bot
commented
May 23, 2019
|
facebook-github-bot
left a comment
There was a problem hiding this comment.
@cpojer has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.
react-native-bot
commented
May 23, 2019
This pull request was successfully merged by Marc Mulcahy in 099be9b. When will my fix make it into a release? | Upcoming Releases |
Summary:
As currently defined, accessibilityStates is an array of strings, which represents the state of an object. The array of strings notion doesn't well encapsulate how various states are related, nor enforce any level of correctness.
This PR converts accessibilityStates to an object with a specific definition. So, rather than:
<View
...
accessibilityStates={['unchecked']}>
We have:
<View
accessibilityStates={{'checked': false}}>
And specifically define the checked state to either take a boolean or the "mixed" string (to represent mixed checkboxes).
We feel this API is easier to understand an implement, and provides better semantic definition of the states themselves, and how states are related to one another.
## Changelog
[general] [change] - Convert accessibilityStates to an object instead of an array of strings.
Pull Request resolved: react#24608
Differential Revision: D15467980
Pulled By: cpojer
fbshipit-source-id: f0414c0ef6add3f10f7f551d323d82d978754278…1144) Summary: This issue fixes#30955 and is a follow up to pr #24608 which added the basic Accessibility functionalities to React Native. TextInput should announce "selected" to the user when screenreader focused. The focus is moved to the TextInput by navigating with the screenreader to the TextInput. This PR adds call to View#setSelected in BaseViewManager https://developer.android.com/reference/android/view/View#setSelected(boolean) The View#setSelected method definition https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/view/View.java ```java /** * Changes the selection state of this view. A view can be selected or not. * Note that selection is not the same as focus. Views are typically * selected in the context of an AdapterView like ListView or GridView; * the selected view is the view that is highlighted. * * param selected true if the view must be selected, false otherwise */ public void setSelected(boolean selected) { if (((mPrivateFlags & PFLAG_SELECTED) != 0) != selected) { // ... hidden logic if (selected) { sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); } // ... hidden logic } } ``` VoiceOver and TalkBack was tested with video samples included below. ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Fixed] - Fix Selected State does not announce when TextInput Component selected on Android Pull Request resolved: #31144 Test Plan: **<details><summary>CLICK TO OPEN TESTS RESULTS</summary>** <p> **ENABLE THE AUDIO** to hear the TalkBack announcing **SELECTED** when the user taps on the TextInput ```javascript <TextInput accessibilityLabel="element 20" accessibilityState={{ selected: true, }} /> ``` | selected is true | |:-------------------------:| | <video src="https://user-images.githubusercontent.com/24992535/111652826-afc4f000-8807-11eb-9c79-8c51d7bf455b.mp4" width="700" height="" /> | ```javascript <TextInput accessibilityLabel="element 20" accessibilityState={{ selected: false, }} /> ``` | selected is false | |:-------------------------:| | <video src="https://user-images.githubusercontent.com/24992535/111652919-c10dfc80-8807-11eb-8244-83db6c327bcd.mp4" width="700" height="" /> | The functionality does not present issues on iOS | iOS testing | |:-------------------------:| | <video src="https://user-images.githubusercontent.com/24992535/111647656-f401c180-8802-11eb-9fa9-a4c211cf1665.mp4" width="400" height="" /> | </p> </details> </p> </details> Reviewed By: blavalla Differential Revision: D27306166 Pulled By: kacieb fbshipit-source-id: 1b3cb37b2d0875cf53f6f1bff4bf095a877b2f0e
Summary
As currently defined, accessibilityStates is an array of strings, which represents the state of an object. The array of strings notion doesn't well encapsulate how various states are related, nor enforce any level of correctness.
This PR converts accessibilityStates to an object with a specific definition. So, rather than:
<View
...
accessibilityStates={['unchecked']}>
We have:
<View
accessibilityStates={{'checked': false}}>
And specifically define the checked state to either take a boolean or the "mixed" string (to represent mixed checkboxes).
We feel this API is easier to understand an implement, and provides better semantic definition of the states themselves, and how states are related to one another.
Changelog
[general] [change] - Convert accessibilityStates to an object instead of an array of strings.
Test Plan
Converted code in RNTester to use the new accessibilityStates API, and modified the checkbox example to support the "mixed" state, which was one of the limitations of the current API which prompted this work.