7 Jul 2019

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 recommemded.

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).

Turn on TalkBack.

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"
        accessibilityComponentType="button"
        accessiblityTraits="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 this StackLayout should be read a button.
  • accessiblityTraits="button" - Tells iOS this StackLayout 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.


Tags: