Alphabet Board in Angular
Intro
I've seen Breaking Bad so many times.
Like honestly at least 4 times.
If you haven't seen it, be careful, it will keep you in front of the TV for several days. In a nutshell, the show is about a high school teacher, named Walter, who gets diagnosed with cancer, and decides to cook meth to pay for his medical bills. Over the course of the show, Walter goes through some extreme lengths to hide his criminal activity- the first time you see it, you think he is so smart! When you get to see it as many times as I have, you notice that he is not only smart, but extremely lucky.
There's another character, Hector Salamanca. He is a former high profile drug runner, and patriarch to a criminal family that is competing for territory with Walter. Since his more involved criminal days, he has had a severe stroke, and communicates with nothing but a bell.
If you have seen the show, you should remember him. If not, you can imagine how frustrating it must be to not be able to communicate with verbal or written language. Salamanca, however, is able to better communicate with the help of his nephews, who are always there for him.
I've been working with accessibility for a few weeks now, and it has totally shifted the way I do things. So when I saw Breaking Bad the last time, I was really interested in finding out a way that the characters in the show could have communicated with Salamanca.
There's one scene in which Salamanca is trying to expose Walter as an infamous meth manufacturer to his nephew Tuco, but Tuco isn't able to properly understand what his uncle is trying to say. At that moment, I was thinking, if only they both knew Morse, right?.
Later on, Salamanca gets reunited with his other nephews, Leonel and Marcos. Then, something incredible happens. They used a Ouija board to communicate with him. At that time I thought, WOW, that's much better than Morse, I even felt dumb for not thinking of it.
Then, Salamanca is sent to a nursing home where he has access to an alphabet board, specifically designed to help non-verbal people communicate. At that point, I felt like designing something around the use of a Ouija board was just reinventing the wheel.
So let's face it, the rule of thumb is if we are looking to solve a problem, the first thing you should do is to search for how others are dealing with it now. Doing so will probably lead you in the right direction. To feel better, I decided to do an Angular application with a digital alphabet board.
What's an alphabet board?
Also referred to as a letter board, an alphabet board is a tool, used by people with certain disabilities, to communicate with others. Users do this by pointing to symbols on the board. These symbols include letters, numbers, signs, and even frequently used words.
I started thinking that if I was going to learn about accessibility, working with an accessibility tool is the best way to go. An alphabet board seemed like a fun idea- listing the alphabet, going through all the letters, allowing the user to react to letters as a manner of input to build phrases. I decided to use the click as the interaction for this example, but it can be changed to anything else.
When using non-digital boards, there's often someone holding the board and systematically scanning through each symbol, giving the user the opportunity to select symbols using a mutually agreed upon signal. The digital version has to automatically go through the letters, and select when receiving clicks.
Now that you have an idea of what this will look like, let's go back to accessibility concepts in order to understand how to properly tackle the project.
Accessibility
Accessibility, as it relates to digital technologies, refers to the design of products, devices, services, or environments, so they can be usable by people with disabilities.
You may already be thinking of ideas to optimize the board's design and function. Your initial thought may be to add some kind of outline to the active letter while going through the alphabet. But what if the user has a visual impairment? That leads us to the first principle in WCAG, Perceivable.
Perceivable
Users must be able to perceive the information being presented (it can't be invisible to all of their senses). WCAG
In order to say that the alphabet tool is truly accessible, users with visual impairments have to be able to use it. There has to be some mechanism to let the user know the currently active letter by sound.
Although it may look like this is the only principle you are applying, if you create an alphabet board that can be easily placed in HTML, users like Salamanca will be able to best operate this tool. This falls into the second principle in WCAG, Operable.
Operable
Users must be able to operate the interface (the interface cannot require interaction that a user cannot perform). WCAG
Helping users like Salamanca use web applications is taking this principle to the next level. It can literally change lives.
Solution
Now, instead of teaching Morse to all patients and nurses, let's build an easy to use alphabet board for people who are non-verbal.
In the previous image, you can see the tool built by IBM for Stephen Hawking. I didn't have a huge crew to pull this off, so I'm going to walk you through a simpler version I created.
Design
The alphabet should be stored as a list of letters; the user interface has to show all the letters in the alphabet, separated by space. It has to have a time interval while the letter is active. When the user clicks, the currently active letter is stored as part of the word.
In order for it to work, there has to be some kind of store, keeping track of the state of the letters that have been added to the word.
Implementation
Let's get to it. Our first step is to build the array of letters. The standard use for electronic communication encoding is named ASCII, in which the upper case letter A is represented by the integer 65. Since it's ordered, we can assume that 66 is upper cased B, and so on, until we reach the length of the alphabet (26).
One of the possible ways to generate an array containing the integers from 65 to 90 in typescript is:
const charCodes = Array.from(Array(26), (_, index) => 65 + index);
You may be wondering, Now what? The user has to do the math to see the current letter?
The short answer is no.
The long answer is that we can use a custom pure pipe to map the charCodes to their respective letter. That pipe can look like this:
@Pipe({
name: 'char'
})
export class CharPipe implements PipeTransform {
transform(keyCode: number) {
return String.fromCharCode(keyCode);
}
}
Which can be used this way:
<span>{{ charCode | char }}</span>
Our next step will be to display them in the UI for the user. That can be done like this:
<span *ngFor="let charCode of charCodes">
{{ charCode | char }}
</span>
What about the active letter? How will the user be visually notified of the currently active letter? That's easy. We create a modifier class in css for that. It can be something like this:
.active {
outline: 2px solid red;
}
The Alphabet board is now pretty useless. We need it to move if we want to allow users to use it by themselves.
RxJs to the rescue!
For the board to move, it is required to have an interval running that will loop through the items in the letters array. We want it to go back to the start once it reaches the end of the list. Also, the .active
class depends on the currently active letter, so you are going to need some Angular magic too.
index$ = timer(0, 2000).pipe(map(tick => tick % (this.letters.length + 1)));
<span
*ngFor="let charCode of charCodes; let i = index"
[ngClass]="{active: (index$ | async) === i}">
{{ charCode | char }}
</span>
We are close! The board is there, and it already moves automatically. Now is the time to listen to interactions, and save the currently selected letter, as well as the word stored so far.
select = new Subject();
word$ = this.select.pipe(
withLatestFrom(this.index$, (_, index) => String.fromCharCode(index)),
scan((state: string, letter: string) => state + letter, '')
);
handleClick = () => {
this.select.next();
}
<div (click)="handleClick()">
<span
*ngFor="let charCode of charCodes; let i = index"
[ngClass]="{active: (index$ | async) === i}">
{{ charCode | char }}
</span>
<span>{{ word$ | async }}</span>
</div>
You just did it! Your users are able to write words with it.
But what if I told you that's not completely true?
Although there's a visual way to know the active letter, what about blind users? Remember, we are talking about inclusion here. You'll need to find a way to automatically notify screen reader users of which letter is currently active, and you will need to create a way to read out the word written so far.
Thankfully ARIA exists, and it has a property that does exactly what we need. I'm not going to talk about ARIA specifically in this article, but you'll need it to get your alphabet board to the next level. To achieve this, you can use aria-live property.
<div (click)="handleClick()">
<span aria-live="assertive">{{ index$ | async | char }} is active.</span>
<span
*ngFor="let charCode of charCodes; let i = index"
[ngClass]="{active: (index$ | async) === i}">
{{ charCode | char }}
</span>
<span aria-live="assertive">{{ word$ | async }}</span>
</div>
And now, if you turn on a screen reader, you'll see how it notifies the active letter, as well as the word written so far.
In case you don't want to create your own board, you can access my version of the alphabet board which looks like this:
NOTE: In order for the alphabet board to start, you have to click.
Conclusion
To wrap this up, I have to say that I personally had a lot of fun doing the Alphabet Board, and I really hope you do too. Many think that accessibility is a matter of following rules and compliance, but there is more to it. It is a way of designing what we build.
NOTE: This article is not related to compliance and rules. The intention is to give you a broader view of the accessibility aspect. If you are interested in being WCAG compliant, I'll release a new article about that soon.
Icons made by Nikita Golubev from Flaticon