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 thisStackLayout
should be read a button.accessiblityTraits="button"
- Tells iOS thisStackLayout
should 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.