A11y First
& Everyone Wins

More Composable, Intuitive & Testable

Ava Gaiety Wroten

Ava Wroten
She/Her

Software Engineer at Allovue

On Gitlab @gaiety Or Github @sharpshark28

We'll Discuss

A project feature saved by A11y

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

Feature:

Item Reordering

Mouse Drag & Drop

Do we support Touch?

What about A11y?

A11Y

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

Accessibility

Equity

World Health Organization

15% of the World
lives with some form of disability

Degrees of Disabilities

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

Web assistive technologies commonly help with...

  • Vision
  • Hearing
  • Movement

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

I build software for humans

So I did some research...

W3C Pattern Rearrangable Listbox

ember-sortable on ember observer

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> ```

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

Implementation Details

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

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>
            

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

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']);
            });
          

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! 🎉

Team Wins

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

v2.x.x ember-sortable

Where do we go from here?

What We Discussed

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

Allovue

We are hiring!

Ava's Challenge to You

Hire someone different than you.

Make A11y a priority at your next design meeting!

Thank you