# A11y First
& Everyone Wins

## More Composable, Intuitive & Testable

Ava Gaiety Wroten

Ava Wroten
She/Her

Software Engineer at

On Gitlab @gaiety Or Github @sharpshark28

...where we build software for K-12 School Districts. You can also find me doing open source work on Gitlab or Github.

## We'll Discuss

A project feature saved by A11y

- Adding Functionality w/ Composable Components
- Equitable & Discoverable UX
- Automation Testing

This is a success story. We'll discuss these terms as we go.

## Feature:

### Item Reordering

Mouse Drag & Drop

Do we support Touch?

What about A11y?

Prior to Allovue, I was assigned a ticket with a simple feature request and no design. Sounds simple enough. Perhaps, too "simple".

A11Y

A....11.....Y

Accessibility

We've seen "A11y" on these slides a lot. Expanded out A11y means Accessibility because it has 18 characters. Acronym.

Equity

I was tasked with delivering a feature that not everyone could use. This felt unfair locking out opportunities to use parts of the app from some users. At Allovue we talk Equity a lot.
World Health Organization

## 15% of the World
lives with some form of disability

A great many talks have been giving trying to sell A11y. I merely wish to set the stage for my motivations here.

## Degrees of Disabilities

Limited mobility, muscle slowness, tremors, low vision, color blindness, partial hearing loss, etc

There are other forms of disability as well as varying degrees of disability. People are human, we have differing levels of ability. Often disabilities are invisible.

Web assistive technologies commonly help with...

- Vision
- Hearing
- Movement

👩🏽‍🔬 👨🏾‍🎨 👩🏻‍🔧 👨🏼‍✈️

I build software for humans

I wouldn't be happy with myself if I shipped software that was completely unusable to some users in a shortsighted fashion.

So I did some research...

W3C Pattern Rearrangable Listbox

World-Wide-Web Consortium. Rearrangable Listbox pattern. This UI felt intuitive because it used existing UI elements and keyboard shortcuts I was familiar with. INTERACT WITH FORM.

Ember Observer ranks and describes Ember Addons. #26 of top 100 addons. Score of 10. Top 10% in terms of downloads. Heavily used solid addon.

## ember-sortable

✔️ Mouse Drag & Drop

✔️ Touch Drag & Drop

✔️ High Ember Observer Ranking

## Component Structure

ember-sortable ```html.hbs <SortableGroup> <SortableItem> ```
Custom Wrappers ```html.hbs <SortableGroupAccessible> <SortableItemAccessible> ```
Ember Sortable offers two composable components. I introduced two more so as not to have to Reopen or Fork the addon.

## Composed Components

index.hbs

```html.hbs <SortableGroupAccessible> <SortableGroup> {{#each this.items as | item |}} <SortableItem> <MyItemComponent /> </SortableItem> {{/each}} </SortableGroup> </SortableGroupAccessible> ```

Heres the final result...

https://gitlab.com/gaiety/sortable-recipes

Demo app. INTERACT WITH MOUSE. INTERACT WITH KEYBOARD. SHOW FOCUS AND ENTER TO ACTIVATE LINKS.

## Implementation Details

https://gitlab.com/gaiety/sortable-recipes

Link is in #ember-conf on Discord.

## Splattributes

index.hbs

                <SortableGroupAccessible
                  tabindex="0"
                  class="border focus:border-teal-400"
                > Foo </SortableGroupAccessible>

sortable-group-accessible.hbs

                  <div ...attributes>
                    {{yield}}
                  </div>

rendered html

                  <div tabindex="0" class="border focus:border-teal-400"
                  > Foo </div>

Useful with glimmer components that dont have a default div wrapper. Useful with composability. Moves implementation details to parent.

## Events & Modifiers

sortable-group-accessible.hbs

                <div
                  {{on 'focus' this.handleFocus}}
                  {{on 'blur' this.handleBlur}}
                  {{key-up this.handleArrowUp key='ArrowUp'}}
                  {{key-up this.handleArrowDown key='ArrowDown'}}

modifiers/key-up.js

                  import { modifier } from 'ember-modifier';
                  const listener = (evt) => {
                    if (!desiredKey || desiredKey === evt.key) handler(evt);
                  }
                  export default modifier(function keyUp(element, [handler], { key: desiredKey }) {
                    element.addEventListener('keyup', listener);
                    return () => { element.removeEventListener('keyup', listener); }
                  });

## Testing Details

## @ember/test-helpers

- render
- click
- triggerEvent
- triggerKeyEvent

Automatically imported for `render` in Rendering tests. Commonly people find `click`. Less common and essential to this story is `triggerEvent` and `TriggerKeyEvent`.

## Modifier Rendering Tests

modifiers/key-up-test.js

                test('it can listen for specific key up events', async function(assert) {
                  this.keyUp = ({ key }) => {
                    assert.equal(key, 'Enter');
                    assert.step('key up');
                  };
                  await render(hbs`
                    <div {{key-up this.keyUp}} data-test-id='keyup'></div>`);
                  let selector = '[data-test-id=keyup]';
                  await triggerKeyEvent(selector, 'keyup', 'Enter');
                  assert.verifySteps(['key up']);
                });

Start at `render` with modifier on a generic div. Async `triggerKeyEvent`. `step` and `verifySteps` for async testing.

## Application Testing Reordering

index-test.js

                assert.dom(findAll('[data-test-id=item]')[0]).hasText('Item 1');
                assert.dom(findAll('[data-test-id=item]')[1]).hasText('Item 2');

                await triggerEvent('[data-test-id=group]', 'focus');
                await click('[data-test-id=sort-down]');

                assert.dom(findAll('[data-test-id=item]')[0]).hasText('Item 2');
                assert.dom(findAll('[data-test-id=item]')[1]).hasText('Item 1');

🎉 A11y allowed us to test reordering! 🎉
Wins on next slide. Be excited here. Mention quick feedback loop for green tests, refactoring, design changes.

## Team Wins

- Quick Feedback Loop
  - ...with development
  - ...with design
  - ...with project managers
- Sign off for UX
- Less stress on QA
- Less scope creep

TDD, felt safe knowing that functionality would not break as we fine tuned functionality and design. Paired with design on various states. QA reassured we had automation tests. Less having to go back later to implement A11y later as an afterthought.

v2.x.x ember-sortable

Since this feature shipped there's been a release of ember-sortable v2 that ships with A11y built in. INTERACT WITH IT.

## Where do we go from here?

- A11y Screen Announcements
- ember-sortable v2.2.x modifiers
- ember-a11y-testing
- ember-cli-template-lint

## What We Discussed

- Adding Functionality w/ Composable Components
- Equitable & Discoverable UX
- Automation Testing A11y

We are hiring!

K-12 School Districts. Equitable. Shape Up.

## Ava's Challenge to You

Hire someone different than you.

Make A11y a priority at your next design meeting!

Hire someone different than you: Race, Religion, Orientation, Gender, megablocks VS Legos. And, finally, make A11y a priority. You may be surprised how many people thank you for it.

Thank you