Accessibility

This document will cover accessibility aspect of the mobile application and focus on VoiceOver and Talkback for both platforms.

Accessibility ID is mainly used for cycling through components and reading them out to the user. Native components like HeaderBar, StatusBar or BottomTabbar covers it by default. On your implementation, you should consider being as user friendly as possible.

You should make your components understandable and declarative as possible for visually impaired users.

Assigning Accessibility ID

API Reference 1: http://ref.smartface.io/beta/#!/api/UI.View-property-accessible

API Reference 2: http://ref.smartface.io/beta/#!/api/UI.View-property-accessibilityLabel

The platforms assign accessible fields for the views it sees fit by default. However, there are situations that requires you to assign accessibility properties yourself.

In order to assign an accessibility ID, you should set those variables correctly.

import View from 'sf-core/ui/view';
const view1 = new View();
view1.accessible = true; // This will make the item reachable by accessibility tools
view1.accessibilityLabel = "This is an empty view"; // This text will be read aloud in voiceover tools.

Tips & Tricks on Assigning Accessibility ID

Nested Views

In your nested views, the parent view will be accessible by default and accessibility features will not be able to reach those children. In order to tackle it, you need to set accessible property of child to true.

import FlexLayout from 'sf-core/ui/flexlayout';
const flexParent = new FlexLayout();
const flexChild = new FlexLayout();
flexParent.addChild(flexChild);
flexChild.accessible = true; // This will make the children accessible by accessibility tools.

Focusable Views like TextBox

Views that contain focusable fields like TextBox or MaterialTextBox will be handled by the operating system by default and they will be accessible. However, in some cases those views shouldn't be clickable (e.g should open a dialog) to handle some other operations. In order to tackle this, you should set the accessible value of TextBox to false and touch actions should be handled by the parent layout.

import TextBox from 'sf-core/ui/textbox';
import FlexLayout from 'sf-core/ui/flexlayout';
import Dialog from 'sf-core/ui/dialog';
const dialog = new Dialog();
dialog.layout.onTouchEnded = () => dialog.hide();
const textBox1 = new TextBox();
const flexWrapper = new FlexLayout();
flexWrapper.android.onInterceptTouchEvent = () => true;
flexWrapper.onTouchEnded = () => {
dialog.show();
};
textBox.touchEnabled = false; // Note that textBox lost its purpose to handle inputs.
textBox.accessible = false; // In this case, this textbox shouldn't be accessible, to prevent typing in it.
flexWrapper.addChild(textBox1); // flexWrapper is the parent of textBox1.

As stated in the touch guide, Android handles the touch from children to parent. Therefore, we had our flexWrapper to steal the event from the children (textBox1) by assigning onInterceptTouchEvent function. On iOS, touches are handled from the parent first, so setting touchEnabled to false will be enough.

MaterialTextBox utility itself is a MaterialTextBox wrapped in a FlexLayout itself.

Refer to the guide below for more information about touch handling: