Accessible baseline components for Vue 3

Insights into a work in progress

"I don't really know enough about A11y"

Me, ~December 2019

"I really want to start dogfooding* Vue 3"

also me, ~December 2019

"I really want to start dogfooding* Vue 3"

also me, ~December 2019

Eating your own dog food or dogfooding is the practice of an organization using its own product.

"

"

   A11y

+ Vue 3

       Composition API

+  Typescript
---------------------

= Fun! 😍

Well, turns out, A11y is HARD!

...but still fun!

What did I do?

I started to build my own component library.

Because that's what a web developer does.

Work in Progress!

Text

1500

Component Libraries

Component Libraries

1500

1501

Component Libraries

<ListBox v-model="selected">
  <ul>
    <ListBoxItem 
      tag="li"
      v-for="item in items"
      :item="item"
    >
      {{ item }}  
    </ListBoxItem>
  </ul>
</Listbox>
<div role="listbox">
 <ul>
    <li 
      role="option"
      tabindex="0" 
      id="randomID1"
      aria-selected="true"
    >
      Item A
    </li>
    <li 
      role="option"
      tabindex="-1" 
      id="randomID-2"
      aria-selected="false"
    >
      Item B
    </li>
    <li 
      role="option"
      tabindex="-10" 
      id="randomID-3"
      aria-selected="false"
    >
      Item C
    </li>
  </ul>
</div>
  • No styling
  • tags customizable
  • proper a11y roles, attributes and behaviours
  • parent and children use provide/inject to coordinate
<template>
  <div v-bind="buttonAttributes">
    I will behave like an accessible button!
  </div>
</template>
<script>
import { ButtonProps, useButton } from '@varia/Button'

export default defineComponent({
  props: ButtonProps,
  setup(props) {
  
    const buttonAttributes = useButton(props)
    
    return {
      buttonAttributes
    }
  }
})
</script>
  • All components can be used as a composable*
  • compose behaviours to build your own accessible components

composable: function using Vue's composition API

<template>
  <Button>
    I will behave like an accessible button!
  </Button>
</template>
<script>
import { ButtonProps, Button } from '@varia/Button'

export default defineComponent({
  props: ButtonProps,
  components: {
    Button,
  },
  setup(props) {
   // nothing
  }
})
</script>
  • Wrap components with your own component
  • no Composition API necessary
  • but means: you now render 2 components to create 1 Button.

DEMO TIME

Next Steps

  1. Open the repo (tonight!)
  2. Build a small team
  3. Define Roadmap for 1st release
    (just a few components)
  4. Get Test coverage up
  5. Write docs
  6. Get feedback from A11y experts

Previous Art

Made with Slides.com