Accessible NativeScript - Part 1 - The Setup
This is the first article in a series about making NativeScript app accessible, using the plugin @nota/nativescript-accessibility-ext that my team been developed for our employer, Nota.
Two years have passed since I wrote my last article on and a lot has happend since when.
Setup
First things first, lets set a new NativeScript angular project with the plugin.
Note: NativeScript core and Vue are also supported.
Source code is available here.
Step 1
Create a new project with the nativescript cli and add the plugin.
tns create --ng tns-a11y-playground
cd tns-a11y-playground && tns plugin add @nota/nativescript-accessibility-ext
Step 2
Import NotaAccessibilityExtModule into your AppModule (for NativeScript Core and Vue - see the readme). This extends the NativeScript View classes and setup the various helpers needed.
Edit src/app/app.module.ts and add these two line:
import { NgModule, NO_ERRORS_SCHEMA } from "@angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NotaAccessibilityExtModule } from '@nota/nativescript-accessibility-ext/angular'; /** add this line **/
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { ItemsComponent } from "./item/items.component";
import { ItemDetailComponent } from "./item/item-detail.component";
@NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule,
NotaAccessibilityExtModule, /** add this line **/
],
declarations: [
AppComponent,
ItemsComponent,
ItemDetailComponent
],
providers: [],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AppModule { }
Step 3 - Optional but highly recommended.
Import the extension to the nativescript-theme-core into your src/app.css.
Edit src/app.css and add a single line:
@import '~nativescript-theme-core/css/core.light.css';
@import '../node_modules/@nota/nativescript-accessibility-ext/css/a11y.css'; /** <-- add this line **/
This enables this css helper classes and font-scaling.
Testing the results
When developing an accessible app, I recommend you try out the results for yourself.
On iOS
The screen reader on iOS is called VoiceOver. It is only available on hardware devices.
(Enabling and using VoiceOver)[https://support.apple.com/guide/iphone/turn-on-and-practice-voiceover-iph3e2e415f/ios]
You can use the Accessibility Inspector from XCode to inspect the App on the simulator. You find it by opening XCode -> Going to the Xcode -> Open Developer Tools -> Accessibility Inspector
On Android
The screen reader for Android is called TalkBack (some vendors rebrand it. Samsung call their version Voice Assistant).
Using the Volume key shortcut.
Install Talkback on the emulator
Talkback isn’t installed by default on the android emulator, but can easily be installed.
Start by launching the emulator.
Checkout, build and install talkback.
git checkout https://github.com/google/talkback.git
cd talkback
./gradlew installDebug
Enabling TalkBack
Can also be enabled via a shortcut see: here
Lets get started
We’ll make the ListView more accessible be changing from:
<ActionBar title="My App" class="action-bar"> </ActionBar>
<GridLayout class="page">
<ListView [items]="items" class="list-group">
<ng-template let-item="item">
<Label [nsRouterLink]="['/item', item.id]" [text]="item.name" class="list-group-item"></Label>
</ng-template>
</ListView>
</GridLayout>
To this:
<ActionBar title="My App" class="action-bar"> </ActionBar>
<GridLayout class="page">
<ListView [items]="items" class="list-group">
<ng-template let-item="item">
<StackLayout
accessible="true"
accessibilityRole="button"
[accessiblityLabel]="item.name"
class="list-group-item"
[nsRouterLink]="['/item', item.id]"
>
<Label [text]="item.name"></Label>
</StackLayout>
</ng-template>
</ListView>
</GridLayout>
We wrapped the Label in a StackLayout (NativeScript does this internally) and settings a few new attributes.
accessible- Marks the element as focusable for the screen reader.accessibilityComponentType="true"- Tells Android thisStackLayoutshould be read a button.accessiblityTraits="button"- Tells iOS thisStackLayoutshould be read a button.accessiblityLabel="...."- The Label being read by the screen render.
When the user traverse the ui with his/hers finger, each ListView will be read as:
- TalkBack:
Button. <Label> - iOS:
<Label>. Button
Next:
In the next article I’ll cover labeling of elements.