Q-btn-dropdown ARIA accessibility - arrow keys



  • I am using QBtnDropdown in my app and want to follow the ARIA standards: one should be able to focus on items in the dropdown by using the up and down arrow keys.

    So far, following https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html, I have this:

    <q-btn-dropdown aria-haspopup="listbox"
        class="glossy q-ml-md q-my-md"
        color="primary"
        :label="chosen"
      >
        <q-list role="listbox" tabindex="-1">
          <q-item role="option"
                  v-for="opt in options"
                  clickable
                  v-close-popup
                  @click="onItemClick(opt)"
           >
             <q-item-section>
                <q-item-label>{{ opt }}</q-item-label>
             </q-item-section>     
          </q-item>
         </q-list>
    </q-btn-dropdown>
    

    This just scrolls up and down the page when the dropdown is selected and I use the arrow keys.
    I am new to ARIA… do I have to implement the focusing functionality myself, for example like this https://dev.to/emmawedekind/creating-a-custom-accessible-drop-down-3gmo ? Or is there something I could add to my project so that I don’t have to implement it all myself?



  • I did end up implementing the functionality myself (fingers crossed quasar will implement it out-of-the-box for its components in the near future), although it wasn’t as complicated as what I linked to seems since I used a ref on each item like so:

          <q-item
            tabindex="-1"
            role="option"
            v-for="(opt, index) in options"
            :key="opt"
            :ref="opt"
            clickable
            v-close-popup
            @click="onItemClick(opt)"
            @keydown.up.prevent="focusOn(index - 1)"
            @keydown.down.prevent="focusOn(index + 1)"
          >
    

    then in the script:

    focusOn(index) {
        this.$refs[this.options[index]][0].$el.focus();
        this.chosen = this.options[index];
        //plus bounds checking code
    }      
    

    In addition to this, I

    • put listeners on q-btn-dropdown to open it when the down arrow or enter button are pressed and, @show, focus on the currently/last chosen element
    • put listener on q-list to exit dropdown (and indicate the last focused item as selected) when tab is pressed


  • @btree nice solution, moved to “Useful Tips”.