Deploy website

Deploy website version based on ae2458fdc8183d12aa5467dd597ba4f531a62d90
This commit is contained in:
Website Deployment Script
2018-08-25 14:56:32 +00:00
parent dd6c9efbb7
commit 6f42c3fee1
5 changed files with 68 additions and 68 deletions
@@ -33,10 +33,10 @@
<p>As technology advances and mobile apps become increasingly important to everyday life, the necessity of creating accessible applications has likewise grown in importance.</p>
<p>React Native's limited Accessibility API has always been a huge pain point for developers, so we've made a few updates to the Accessibility API to make it easier to create inclusive mobile applications.</p>
<h2><a class="anchor" aria-hidden="true" id="problems-with-the-existing-api"></a><a href="#problems-with-the-existing-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problems With the Existing API</h2>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - AccessibilityComponentType (android) and AccessibilityTraits(iOS)</h3>
<p><code>AccessibilityComponentType</code> and <code>AccessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p><code>accessibilityComponentType</code> and <code>accessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<ol>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>AccessibilityTraits</code> on iOS allows 17 different values while <code>AccessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>AccessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>AccessibilityComponentType</code> allows only a single value.</li>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>accessibilityTraits</code> on iOS allows 17 different values while <code>accessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>accessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>accessibilityComponentType</code> allows only a single value.</li>
<li><strong>There is very limited functionality on Android.</strong> With the old property, the only UI elements that Talkback were able to recognize were “button,” “radiobutton_checked,” and “radiobutton_unchecked.”</li>
</ol>
<h3><a class="anchor" aria-hidden="true" id="problem-two-non-existent-accessibility-hints"></a><a href="#problem-two-non-existent-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Two: Non-existent Accessibility Hints:</h3>
@@ -44,17 +44,17 @@
<h3><a class="anchor" aria-hidden="true" id="problem-three-ignoring-inverted-colors"></a><a href="#problem-three-ignoring-inverted-colors" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Three: Ignoring Inverted Colors:</h3>
<p>Some users with vision loss use inverted colors on their mobile phones to have greater screen contrast. Apple provided an API for iOS which allows developers to ignore certain views. This way, images and videos aren't distorted when a user has the inverted colors setting on. This API is currently unsupported by React Native.</p>
<h2><a class="anchor" aria-hidden="true" id="design-of-the-new-api"></a><a href="#design-of-the-new-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Design of the New API</h2>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios"></a><a href="#solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining AccessibilityComponentType(android) and AccessibilityTraits(iOS)</h3>
<p>In order to solve the confusion between accessibilityComponentType and accessibilityTraits, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p>In order to solve the confusion between <code>accessibilityComponentType</code> and <code>accessibilityTraits</code>, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<p><strong>Background</strong></p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a UIAccessibilityTraits element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a <code>UIAccessibilityTraits</code> element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On Android however, <code>AccessibilityComponentType</code> is a concept that was made up by React Native, and doesn't directly map to any properties in Android. Accessibility is handled by an accessibility delegate. Each view has a default accessibility delegate. If you want to customize any accessibility actions, you have to create a new accessibility delegate, override specific methods you want to customize, and then set the accessibility delegate of the view you are handling to be associated with the new delegate. When a developer set <code>AccessibilityComponentType</code>, the native code created a new delegate based off of the component that was passed in, and set the view to have that accessibility delegate.</p>
<p><strong>Changes Made</strong></p>
<p>For our new property, we wanted to create a superset of the two properties. We decided to keep the new property modeled mostly after the existing property <code>accessibilityTraits</code>, since <code>accessibilityTraits</code> has significantly more values. The functionality of Android for these traits would be polyfilled in by modifying the Accessibility Delegate.</p>
<p>There are 17 values of UIAccessibilityTraits that <code>AccessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: AccessibilityRole and AccessibilityState.</p>
<p><strong><code>AccessibilityRole</code></strong></p>
<p>The new property, <code>AccessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<p>There are 17 values of UIAccessibilityTraits that <code>accessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: <code>accessibilityRole</code> and <code>accessibilityState</code>.</p>
<p><strong><code>accessibilityRole</code></strong></p>
<p>The new property, <code>accessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<ul>
<li><code>none</code></li>
<li><code>button</code></li>
@@ -69,22 +69,22 @@
<li><code>imagebutton</code></li>
</ul>
<p>This property only allows one value to be passed in because UI elements generally don't logically take on more than one of these. The exception is image and button, so we've added a role imagebutton that is a combination of both.</p>
<p><strong><code>AccessibilityStates</code></strong></p>
<p>The new property, <code>AccessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<p><strong><code>accessibilityStates</code></strong></p>
<p>The new property, <code>accessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<ul>
<li><code>selected</code></li>
<li><code>disabled</code></li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="solution-two-adding-accessibility-hints"></a><a href="#solution-two-adding-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution Two: Adding Accessibility Hints</h3>
<p>For this, we added a new property, accessibilityHints. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>AccessibilityHints</code></strong></p>
<p>For this, we added a new property, <code>accessibilityHint</code>. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>accessibilityHint</code></strong></p>
<p>This property takes in the accessibility hint to be read in the form of a String.</p>
<p>On iOS, setting this property will set the corresponding native property AccessibilityHint on the view. The hint will then be read by Voiceover if Accessibility Hints are turned on in the iPhone.</p>
<p>On Android, setting this property appends the value of the hint to the end of the accessibility label. The upside to this implementation is that it mimics the behavior of hints on iOS, but the downside to this implementation is that these hints cannot be turned off in the settings on Android the way they can be on iOS.</p>
<p>The reason we made this decision on Android is because normally, accessibility hints correspond with a specific action (e.g. click), and we wanted to keep behaviors consistent across platforms.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-to-problem-three"></a><a href="#solution-to-problem-three" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution to Problem Three</h3>
<p><strong><code>AccessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to javascript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<p><strong><code>accessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to JavaScript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<h2><a class="anchor" aria-hidden="true" id="new-usage"></a><a href="#new-usage" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>New Usage</h2>
<p>These new properties will become available in the React Native 0.57 release.</p>
<h3><a class="anchor" aria-hidden="true" id="how-to-upgrade"></a><a href="#how-to-upgrade" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>How to Upgrade</h3>
@@ -92,21 +92,21 @@
<h4><a class="anchor" aria-hidden="true" id="1-using-jscodeshift"></a><a href="#1-using-jscodeshift" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Using jscodeshift</h4>
<p>The most simple use cases can be replaced by running a jscodeshift script.</p>
<p>This <a href="https://gist.github.com/ziqichen6/246e5778617224d2b4aff198dab0305d">script</a> replaces the following instances:</p>
<pre><code class="hljs">AccessibilityTraits=“trait”
AccessibilityTraits={[“trait”]}
<pre><code class="hljs">accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}
</code></pre>
<p>With</p>
<pre><code class="hljs">AccessibilityRole= “trait”
<pre><code class="hljs">accessibilityRole= “trait”
</code></pre>
<p>This script also removes instances of <code>AccessibilityComponentType</code> (assuming everywhere you set <code>AccessibilityComponentType</code>, you would also set <code>AccessibilityTraits</code>).</p>
<h4><a class="anchor" aria-hidden="true" id="2-using-a-manual-codemod"></a><a href="#2-using-a-manual-codemod" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Using a manual codemod</h4>
<p>For the cases that used <code>AccessibilityTraits</code> that don't have a corresponding value for <code>AccessibilityRole</code>, and the cases where multiple traits were passed into <code>AccessibilityTraits</code>, a manual codemod would have to be done.</p>
<p>In general,</p>
<pre><code class="hljs">AccessibilityTraits= {[“button”, “selected”]}
<pre><code class="hljs">accessibilityTraits= {[“button”, “selected”]}
</code></pre>
<p>would be manually replaced with</p>
<pre><code class="hljs">AccessibilityRole=“button”
AccessibilityStates={[“selected”]}
<pre><code class="hljs">accessibilityRole=“button”
accessibilityStates={[“selected”]}
</code></pre>
<p>These properties are already being used in Facebook's codebase. The codemod for Facebook was surprisingly simple. The jscodeshift script fixed about half of our instances, and the other half was fixed manually. Overall, the entire process took less than a few hours.</p>
<p>Hopefully you will find the updated API useful! And please continue making apps accessible! #inclusion</p>
@@ -33,10 +33,10 @@
<p>As technology advances and mobile apps become increasingly important to everyday life, the necessity of creating accessible applications has likewise grown in importance.</p>
<p>React Native's limited Accessibility API has always been a huge pain point for developers, so we've made a few updates to the Accessibility API to make it easier to create inclusive mobile applications.</p>
<h2><a class="anchor" aria-hidden="true" id="problems-with-the-existing-api"></a><a href="#problems-with-the-existing-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problems With the Existing API</h2>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - AccessibilityComponentType (android) and AccessibilityTraits(iOS)</h3>
<p><code>AccessibilityComponentType</code> and <code>AccessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p><code>accessibilityComponentType</code> and <code>accessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<ol>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>AccessibilityTraits</code> on iOS allows 17 different values while <code>AccessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>AccessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>AccessibilityComponentType</code> allows only a single value.</li>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>accessibilityTraits</code> on iOS allows 17 different values while <code>accessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>accessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>accessibilityComponentType</code> allows only a single value.</li>
<li><strong>There is very limited functionality on Android.</strong> With the old property, the only UI elements that Talkback were able to recognize were “button,” “radiobutton_checked,” and “radiobutton_unchecked.”</li>
</ol>
<h3><a class="anchor" aria-hidden="true" id="problem-two-non-existent-accessibility-hints"></a><a href="#problem-two-non-existent-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Two: Non-existent Accessibility Hints:</h3>
@@ -44,17 +44,17 @@
<h3><a class="anchor" aria-hidden="true" id="problem-three-ignoring-inverted-colors"></a><a href="#problem-three-ignoring-inverted-colors" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Three: Ignoring Inverted Colors:</h3>
<p>Some users with vision loss use inverted colors on their mobile phones to have greater screen contrast. Apple provided an API for iOS which allows developers to ignore certain views. This way, images and videos aren't distorted when a user has the inverted colors setting on. This API is currently unsupported by React Native.</p>
<h2><a class="anchor" aria-hidden="true" id="design-of-the-new-api"></a><a href="#design-of-the-new-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Design of the New API</h2>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios"></a><a href="#solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining AccessibilityComponentType(android) and AccessibilityTraits(iOS)</h3>
<p>In order to solve the confusion between accessibilityComponentType and accessibilityTraits, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p>In order to solve the confusion between <code>accessibilityComponentType</code> and <code>accessibilityTraits</code>, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<p><strong>Background</strong></p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a UIAccessibilityTraits element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a <code>UIAccessibilityTraits</code> element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On Android however, <code>AccessibilityComponentType</code> is a concept that was made up by React Native, and doesn't directly map to any properties in Android. Accessibility is handled by an accessibility delegate. Each view has a default accessibility delegate. If you want to customize any accessibility actions, you have to create a new accessibility delegate, override specific methods you want to customize, and then set the accessibility delegate of the view you are handling to be associated with the new delegate. When a developer set <code>AccessibilityComponentType</code>, the native code created a new delegate based off of the component that was passed in, and set the view to have that accessibility delegate.</p>
<p><strong>Changes Made</strong></p>
<p>For our new property, we wanted to create a superset of the two properties. We decided to keep the new property modeled mostly after the existing property <code>accessibilityTraits</code>, since <code>accessibilityTraits</code> has significantly more values. The functionality of Android for these traits would be polyfilled in by modifying the Accessibility Delegate.</p>
<p>There are 17 values of UIAccessibilityTraits that <code>AccessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: AccessibilityRole and AccessibilityState.</p>
<p><strong><code>AccessibilityRole</code></strong></p>
<p>The new property, <code>AccessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<p>There are 17 values of UIAccessibilityTraits that <code>accessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: <code>accessibilityRole</code> and <code>accessibilityState</code>.</p>
<p><strong><code>accessibilityRole</code></strong></p>
<p>The new property, <code>accessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<ul>
<li><code>none</code></li>
<li><code>button</code></li>
@@ -69,22 +69,22 @@
<li><code>imagebutton</code></li>
</ul>
<p>This property only allows one value to be passed in because UI elements generally don't logically take on more than one of these. The exception is image and button, so we've added a role imagebutton that is a combination of both.</p>
<p><strong><code>AccessibilityStates</code></strong></p>
<p>The new property, <code>AccessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<p><strong><code>accessibilityStates</code></strong></p>
<p>The new property, <code>accessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<ul>
<li><code>selected</code></li>
<li><code>disabled</code></li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="solution-two-adding-accessibility-hints"></a><a href="#solution-two-adding-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution Two: Adding Accessibility Hints</h3>
<p>For this, we added a new property, accessibilityHints. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>AccessibilityHints</code></strong></p>
<p>For this, we added a new property, <code>accessibilityHint</code>. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>accessibilityHint</code></strong></p>
<p>This property takes in the accessibility hint to be read in the form of a String.</p>
<p>On iOS, setting this property will set the corresponding native property AccessibilityHint on the view. The hint will then be read by Voiceover if Accessibility Hints are turned on in the iPhone.</p>
<p>On Android, setting this property appends the value of the hint to the end of the accessibility label. The upside to this implementation is that it mimics the behavior of hints on iOS, but the downside to this implementation is that these hints cannot be turned off in the settings on Android the way they can be on iOS.</p>
<p>The reason we made this decision on Android is because normally, accessibility hints correspond with a specific action (e.g. click), and we wanted to keep behaviors consistent across platforms.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-to-problem-three"></a><a href="#solution-to-problem-three" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution to Problem Three</h3>
<p><strong><code>AccessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to javascript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<p><strong><code>accessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to JavaScript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<h2><a class="anchor" aria-hidden="true" id="new-usage"></a><a href="#new-usage" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>New Usage</h2>
<p>These new properties will become available in the React Native 0.57 release.</p>
<h3><a class="anchor" aria-hidden="true" id="how-to-upgrade"></a><a href="#how-to-upgrade" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>How to Upgrade</h3>
@@ -92,21 +92,21 @@
<h4><a class="anchor" aria-hidden="true" id="1-using-jscodeshift"></a><a href="#1-using-jscodeshift" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Using jscodeshift</h4>
<p>The most simple use cases can be replaced by running a jscodeshift script.</p>
<p>This <a href="https://gist.github.com/ziqichen6/246e5778617224d2b4aff198dab0305d">script</a> replaces the following instances:</p>
<pre><code class="hljs">AccessibilityTraits=“trait”
AccessibilityTraits={[“trait”]}
<pre><code class="hljs">accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}
</code></pre>
<p>With</p>
<pre><code class="hljs">AccessibilityRole= “trait”
<pre><code class="hljs">accessibilityRole= “trait”
</code></pre>
<p>This script also removes instances of <code>AccessibilityComponentType</code> (assuming everywhere you set <code>AccessibilityComponentType</code>, you would also set <code>AccessibilityTraits</code>).</p>
<h4><a class="anchor" aria-hidden="true" id="2-using-a-manual-codemod"></a><a href="#2-using-a-manual-codemod" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Using a manual codemod</h4>
<p>For the cases that used <code>AccessibilityTraits</code> that don't have a corresponding value for <code>AccessibilityRole</code>, and the cases where multiple traits were passed into <code>AccessibilityTraits</code>, a manual codemod would have to be done.</p>
<p>In general,</p>
<pre><code class="hljs">AccessibilityTraits= {[“button”, “selected”]}
<pre><code class="hljs">accessibilityTraits= {[“button”, “selected”]}
</code></pre>
<p>would be manually replaced with</p>
<pre><code class="hljs">AccessibilityRole=“button”
AccessibilityStates={[“selected”]}
<pre><code class="hljs">accessibilityRole=“button”
accessibilityStates={[“selected”]}
</code></pre>
<p>These properties are already being used in Facebook's codebase. The codemod for Facebook was surprisingly simple. The jscodeshift script fixed about half of our instances, and the other half was fixed manually. Overall, the entire process took less than a few hours.</p>
<p>Hopefully you will find the updated API useful! And please continue making apps accessible! #inclusion</p>
+22 -22
View File
@@ -33,10 +33,10 @@
<p>As technology advances and mobile apps become increasingly important to everyday life, the necessity of creating accessible applications has likewise grown in importance.</p>
<p>React Native's limited Accessibility API has always been a huge pain point for developers, so we've made a few updates to the Accessibility API to make it easier to create inclusive mobile applications.</p>
<h2><a class="anchor" aria-hidden="true" id="problems-with-the-existing-api"></a><a href="#problems-with-the-existing-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problems With the Existing API</h2>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - AccessibilityComponentType (android) and AccessibilityTraits(iOS)</h3>
<p><code>AccessibilityComponentType</code> and <code>AccessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<h3><a class="anchor" aria-hidden="true" id="problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#problem-one-two-completely-different-yet-similar-props-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem One: Two Completely Different Yet Similar Props - accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p><code>accessibilityComponentType</code> and <code>accessibilityTraits</code> are two properties that are used to tell TalkBack on Android and VoiceOver on iOS what kind of UI element the user is interacting with. The two biggest problems with these properties are that:</p>
<ol>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>AccessibilityTraits</code> on iOS allows 17 different values while <code>AccessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>AccessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>AccessibilityComponentType</code> allows only a single value.</li>
<li><strong>They are two different properties with different usage methods, yet have the same purpose.</strong> In the previous API, these are two separate properties (one for each platform), which was not only inconvenient, but also confusing to many developers. <code>accessibilityTraits</code> on iOS allows 17 different values while <code>accessibilityComponentType</code> on Android allows only 4 values. Furthermore, the values for the most part had no overlap. Even the input types for these two properties are different. <code>accessibilityTraits</code> allows either an array of traits to be passed in or a single trait, while <code>accessibilityComponentType</code> allows only a single value.</li>
<li><strong>There is very limited functionality on Android.</strong> With the old property, the only UI elements that Talkback were able to recognize were “button,” “radiobutton_checked,” and “radiobutton_unchecked.”</li>
</ol>
<h3><a class="anchor" aria-hidden="true" id="problem-two-non-existent-accessibility-hints"></a><a href="#problem-two-non-existent-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Two: Non-existent Accessibility Hints:</h3>
@@ -44,17 +44,17 @@
<h3><a class="anchor" aria-hidden="true" id="problem-three-ignoring-inverted-colors"></a><a href="#problem-three-ignoring-inverted-colors" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Problem Three: Ignoring Inverted Colors:</h3>
<p>Some users with vision loss use inverted colors on their mobile phones to have greater screen contrast. Apple provided an API for iOS which allows developers to ignore certain views. This way, images and videos aren't distorted when a user has the inverted colors setting on. This API is currently unsupported by React Native.</p>
<h2><a class="anchor" aria-hidden="true" id="design-of-the-new-api"></a><a href="#design-of-the-new-api" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Design of the New API</h2>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios"></a><a href="#solution-one-combining-accessibilitycomponenttypeandroid-and-accessibilitytraitsios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining AccessibilityComponentType(android) and AccessibilityTraits(iOS)</h3>
<p>In order to solve the confusion between accessibilityComponentType and accessibilityTraits, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios"></a><a href="#solution-one-combining-accessibilitycomponenttype-android-and-accessibilitytraits-ios" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution One: Combining accessibilityComponentType (Android) and accessibilityTraits (iOS)</h3>
<p>In order to solve the confusion between <code>accessibilityComponentType</code> and <code>accessibilityTraits</code>, we decided to merge them into a single property. This made sense because they technically had the same intended functionality and by merging them, developers no longer had to worry about platform specific intricacies when building accessibility features.</p>
<p><strong>Background</strong></p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a UIAccessibilityTraits element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On iOS, <code>UIAccessibilityTraits</code> is a property that can be set on any NSObject. Each of the 17 traits passed in through the javascript property to native is mapped to a <code>UIAccessibilityTraits</code> element in Objective-C. Traits are each represented by a long int, and every trait that is set is ORed together.</p>
<p>On Android however, <code>AccessibilityComponentType</code> is a concept that was made up by React Native, and doesn't directly map to any properties in Android. Accessibility is handled by an accessibility delegate. Each view has a default accessibility delegate. If you want to customize any accessibility actions, you have to create a new accessibility delegate, override specific methods you want to customize, and then set the accessibility delegate of the view you are handling to be associated with the new delegate. When a developer set <code>AccessibilityComponentType</code>, the native code created a new delegate based off of the component that was passed in, and set the view to have that accessibility delegate.</p>
<p><strong>Changes Made</strong></p>
<p>For our new property, we wanted to create a superset of the two properties. We decided to keep the new property modeled mostly after the existing property <code>accessibilityTraits</code>, since <code>accessibilityTraits</code> has significantly more values. The functionality of Android for these traits would be polyfilled in by modifying the Accessibility Delegate.</p>
<p>There are 17 values of UIAccessibilityTraits that <code>AccessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: AccessibilityRole and AccessibilityState.</p>
<p><strong><code>AccessibilityRole</code></strong></p>
<p>The new property, <code>AccessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<p>There are 17 values of UIAccessibilityTraits that <code>accessibilityTraits</code> on iOS can be set to. However, we didn't include all of them as possible values to our new property. This is because the effect of setting some of these traits is actually not very well known, and many of these values are virtually never used.</p>
<p>The values UIAccessibilityTraits were set to generally took on one of two purposes. They either described a role that UI element had, or they described the state a UI element was in. Most uses of the previous properties we observed usually used one value that represented a role and combined it with either “state selected,” “state disabled,” or both. Therefore, we decided to create two new accessibility properties: <code>accessibilityRole</code> and <code>accessibilityState</code>.</p>
<p><strong><code>accessibilityRole</code></strong></p>
<p>The new property, <code>accessibilityRole</code>, is used to tell Talkback or Voiceover the role of a UI Element. This new property can take on one of the following values:</p>
<ul>
<li><code>none</code></li>
<li><code>button</code></li>
@@ -69,22 +69,22 @@
<li><code>imagebutton</code></li>
</ul>
<p>This property only allows one value to be passed in because UI elements generally don't logically take on more than one of these. The exception is image and button, so we've added a role imagebutton that is a combination of both.</p>
<p><strong><code>AccessibilityStates</code></strong></p>
<p>The new property, <code>AccessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<p><strong><code>accessibilityStates</code></strong></p>
<p>The new property, <code>accessibilityStates</code>, is used to tell Talkback or Voiceover the state a UI Element is in. This property takes on an Array containing one or both of the following values:</p>
<ul>
<li><code>selected</code></li>
<li><code>disabled</code></li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="solution-two-adding-accessibility-hints"></a><a href="#solution-two-adding-accessibility-hints" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution Two: Adding Accessibility Hints</h3>
<p>For this, we added a new property, accessibilityHints. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>AccessibilityHints</code></strong></p>
<p>For this, we added a new property, <code>accessibilityHint</code>. Setting this property will allow Talkback or Voiceover to recite the hint to users.</p>
<p><strong><code>accessibilityHint</code></strong></p>
<p>This property takes in the accessibility hint to be read in the form of a String.</p>
<p>On iOS, setting this property will set the corresponding native property AccessibilityHint on the view. The hint will then be read by Voiceover if Accessibility Hints are turned on in the iPhone.</p>
<p>On Android, setting this property appends the value of the hint to the end of the accessibility label. The upside to this implementation is that it mimics the behavior of hints on iOS, but the downside to this implementation is that these hints cannot be turned off in the settings on Android the way they can be on iOS.</p>
<p>The reason we made this decision on Android is because normally, accessibility hints correspond with a specific action (e.g. click), and we wanted to keep behaviors consistent across platforms.</p>
<h3><a class="anchor" aria-hidden="true" id="solution-to-problem-three"></a><a href="#solution-to-problem-three" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Solution to Problem Three</h3>
<p><strong><code>AccessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to javascript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<p><strong><code>accessibilityIgnoresInvertColors</code></strong></p>
<p>We exposed Apple's api AccessibilityIgnoresInvertColors to JavaScript, so now when you have a view where you don't want colors to be inverted (e.g image), you can set this property to true, and it won't be inverted.</p>
<h2><a class="anchor" aria-hidden="true" id="new-usage"></a><a href="#new-usage" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>New Usage</h2>
<p>These new properties will become available in the React Native 0.57 release.</p>
<h3><a class="anchor" aria-hidden="true" id="how-to-upgrade"></a><a href="#how-to-upgrade" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>How to Upgrade</h3>
@@ -92,21 +92,21 @@
<h4><a class="anchor" aria-hidden="true" id="1-using-jscodeshift"></a><a href="#1-using-jscodeshift" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>1. Using jscodeshift</h4>
<p>The most simple use cases can be replaced by running a jscodeshift script.</p>
<p>This <a href="https://gist.github.com/ziqichen6/246e5778617224d2b4aff198dab0305d">script</a> replaces the following instances:</p>
<pre><code class="hljs">AccessibilityTraits=“trait”
AccessibilityTraits={[“trait”]}
<pre><code class="hljs">accessibilityTraits=“trait”
accessibilityTraits={[“trait”]}
</code></pre>
<p>With</p>
<pre><code class="hljs">AccessibilityRole= “trait”
<pre><code class="hljs">accessibilityRole= “trait”
</code></pre>
<p>This script also removes instances of <code>AccessibilityComponentType</code> (assuming everywhere you set <code>AccessibilityComponentType</code>, you would also set <code>AccessibilityTraits</code>).</p>
<h4><a class="anchor" aria-hidden="true" id="2-using-a-manual-codemod"></a><a href="#2-using-a-manual-codemod" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>2. Using a manual codemod</h4>
<p>For the cases that used <code>AccessibilityTraits</code> that don't have a corresponding value for <code>AccessibilityRole</code>, and the cases where multiple traits were passed into <code>AccessibilityTraits</code>, a manual codemod would have to be done.</p>
<p>In general,</p>
<pre><code class="hljs">AccessibilityTraits= {[“button”, “selected”]}
<pre><code class="hljs">accessibilityTraits= {[“button”, “selected”]}
</code></pre>
<p>would be manually replaced with</p>
<pre><code class="hljs">AccessibilityRole=“button”
AccessibilityStates={[“selected”]}
<pre><code class="hljs">accessibilityRole=“button”
accessibilityStates={[“selected”]}
</code></pre>
<p>These properties are already being used in Facebook's codebase. The codemod for Facebook was surprisingly simple. The jscodeshift script fixed about half of our instances, and the other half was fixed manually. Overall, the entire process took less than a few hours.</p>
<p>Hopefully you will find the updated API useful! And please continue making apps accessible! #inclusion</p>
+1 -1
View File
@@ -35,7 +35,7 @@
<ul>
<li>Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.</li>
<li>This is a <code>PureComponent</code> which means that it will not re-render if <code>props</code> remain shallow- equal. Make sure that everything your <code>renderItem</code> function depends on is passed as a prop (e.g. <code>extraData</code>) that is not <code>===</code> after updates, otherwise your UI may not update on changes. This includes the <code>data</code> prop and parent component state.</li>
<li>In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.</li>
<li>In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.</li>
<li>By default, the list looks for a <code>key</code> prop on each item and uses that for the React key. Alternatively, you can provide a custom <code>keyExtractor</code> prop.</li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="props"></a><a href="#props" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Props</h3>
+1 -1
View File
@@ -35,7 +35,7 @@
<ul>
<li>Internal state is not preserved when content scrolls out of the render window. Make sure all your data is captured in the item data or external stores like Flux, Redux, or Relay.</li>
<li>This is a <code>PureComponent</code> which means that it will not re-render if <code>props</code> remain shallow- equal. Make sure that everything your <code>renderItem</code> function depends on is passed as a prop (e.g. <code>extraData</code>) that is not <code>===</code> after updates, otherwise your UI may not update on changes. This includes the <code>data</code> prop and parent component state.</li>
<li>In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate ands momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.</li>
<li>In order to constrain memory and enable smooth scrolling, content is rendered asynchronously offscreen. This means it's possible to scroll faster than the fill rate and momentarily see blank content. This is a tradeoff that can be adjusted to suit the needs of each application, and we are working on improving it behind the scenes.</li>
<li>By default, the list looks for a <code>key</code> prop on each item and uses that for the React key. Alternatively, you can provide a custom <code>keyExtractor</code> prop.</li>
</ul>
<h3><a class="anchor" aria-hidden="true" id="props"></a><a href="#props" aria-hidden="true" class="hash-link"><svg class="hash-link-icon" aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a>Props</h3>