vuetifyjs / vuetify

🐉 Vue Component Framework
https://vuetifyjs.com
MIT License
39.59k stars 6.94k forks source link

[Feature Request] v-data-table Keyboard Support/Navigation #9164

Open mgren21 opened 4 years ago

mgren21 commented 4 years ago

Problem to solve

It appears that keyboard navigation for v-data-tables is not implemented in Vuetify 2+. In Vuetify 1.5.x it was possible to navigate the v-data-table headers and select entries in the table using keyboard commands. I am not sure why these features have been removed.

Proposed solution

It would be ideal for the a11y features previously available in Vuetify 1.5.x to be added back so data tables can be easily navigated with keyboard commands.

albertoaflores commented 4 years ago

+1

genyded commented 4 years ago

This is paramount to us. We moved from Quasar to Vuetify because we needed multi-column sort in our tables. But now if we cannot have key navigation in them after our users are used to it, we'll have to seek yet another alternative. That's a pretty major feature to just wipe with no warning.

mtermoul commented 4 years ago

It seems that when you I have a v-data-table component with show-select property to enable row selection through checkboxes does not support keyboard mode navigation using the tab+space keys! This is a major accessibility issue. After digging deeper I come to find out that the reason the keyboard navigation is not working because the v-simple-checkbox does not handle the keyboard events. So if we fix the v-simple-checkbox keyboard event handling then the v-data-table issues will be fixed. Do you guys agree?

genyded commented 4 years ago

In our case, we didn't have checkbox enabled/used, so it seems like key navigation should work in that scenario and only be disabled if checkbox is being used. Additionally key navigation is typically used in 'cell' editing (not row editing) and in that case row selection would not be needed.

In our case we do not care about checkbox, only key navigation, but if both can work that would be ideal.

mtermoul commented 4 years ago

I think regardless if you are using the show-select or not, v-data-table should support keyboard navigation to be able to claim that vuetify components have accessibility features built-in. However that's not the case for the v-data-table component. So this really remains an open issue and needs to be addressed.

schwoortz commented 3 years ago

@mtermoul Thanks for responding to this issue. We are dealing with this accessibility-issue, too. While keyboard accessibility for checkboxes is really the most important I would like to add these 2 findings:

  1. sort table -> the mouse-clickable TH area is also not accessible via keyboard
  2. pagination -> if one paginates, the focus moves away from the arrow way to the beginning of the HTML document. It would make sense to keep the focus right on that button in order to easily step forward / backward multiple times (without tabbing all the way back to that button)

Do you or does anyone know a manual fix for the checkboxes-issue? Or when an update with this issue fixed might be available?

mtermoul commented 3 years ago

@schwoortz At the moment there is no fix from Vuetify team yet, however there are a couple workarounds to help you remedy these issues. Here is the list of workarounds that I have used:

<v-data-table ...>
   <template v-slot:item.data-table-select="{ item, isSelected }">
        <v-checkbox
            :value="isSelected"
             hide-details
             class="mt-0"
             @change="onItemSelect({ item, value: !isSelected })"
         >
        </v-checkbox>
   </template>
</v-data-table>
<v-data-table ...>
   <template v-slot:header.data-table-select="{ value, indeterminate }">
        <v-checkbox
            :value="value"
            :indeterminate="props.indeterminate"
             hide-details
             class="mt-0"
             @change="onSelectAllChange"
         >
        </v-checkbox>
   </template>
</v-data-table>
<v-data-table ...>
   <template v-slot:footer="{ pagination }">
       ... render your own pagination components here
   </template>
</v-data-table>

Please check out the v-data-table documentation about the slots that it has, and let me know if you have used other ways to address the accessibility issues.

schwoortz commented 3 years ago

@mtermoul Thank you very much for your in depth response and these well explained workarounds. I showed them to our team and they are keen to check it all out. I will get back to you with results as soon as we have any. Thanks again!

vickyrare commented 3 years ago

Have this been fixed in Vuetify 2.4?

cdefy commented 3 years ago

Doesn't seem to be, I just tried to navigate a v-data-table with show-select by keyboard and I can't get to the checkbox :(

joswald76 commented 3 years ago

Is there an update on this?

I wonder how the documentation can list Vuetify as 508 compliant, when this bug is still open: https://next.vuetifyjs.com/en/introduction/why-vuetify/#why-vuetify3f

advaittoraskar007 commented 3 years ago

The lack of this feature is completely breaking our keyboard accessibility since most our UI is based on tables. Any updates on the issue will be really helpful.

schwoortz commented 3 years ago

The team I worked with on a project fixed it with some custom code based on the answer @mtermoul provided (see above). I can try to get back to them and ask for more details. I believe, the issue hasn't yet been fixed in the vuetify core, unfortunately.

flpehr0 commented 2 years ago

Hi everyone --- This should not be a feature request. This is a bug. Accessibility and section 508 compliance issues are baseline functionality and if a keyboard user cannot access a clickable feature then that feature is broken! Please open a bug ticket.

caseybishop commented 2 years ago

Does someone have a working example of the workarounds mentioned?

mauricio-andrade commented 2 years ago

Hi everyone. I'm doing tests about accessibility, and I think that the semantic is the most important thing. Then if you have a table using < th > and < tr >, it's ok. I'm using NVDA to test, and I can access a table using CTRL+ALT+ (Right, Left, Up, Down). Then when I'm using a v-data-table, I can access the < th >, and using < enter > I can change the sort in a column. If I'm using show-select, I can access the checkbox too, navigating in the table, and click < enter > to select. I don't know if I'm correct or not, but I think that you don't need that all parts of your table needs to use tab. Thanks in advance.

Christian-Sibo-ONRR commented 2 years ago

Here's a solution that doesn't require overriding the header slots. That solution wasn't tenable for me because we were already doing a lot of work on the headers and didn't want to repeat code everywhere. I haven't tested this with selectable rows or grouped headers.

This method simply makes the ths focusable and binds the enter key to their normal click handler. Everything else is handled by the browser (eg. focus styling for the span).

<v-data-table
    ...
    :headers="myHeaders"
/>
<script>
    // ...

    methods: {
        columnKeyUp(event) {
            if(event.key !== 'Enter') return

            event.target.click()
        },
    },

    watch: {
        myHeaders: {
            handler() {
                const table = // however you reference your table. eg. this.$refs.table.$el

                if (!table) return

                const sortableColumns = table.querySelectorAll('th.sortable > span:not(.v-icon)')

                sortableColumns.forEach(col => {
                    col.setAttribute('tabindex', '0')

                    col.addEventListener('keyup', this.columnKeyUp)
                })
            },
            immediate: true,
            deep: true,
        },
    },
</script>
jssuttles commented 2 years ago

I don't really like it, but this is what I've had to do for this. On keypress click the ref. Add tabindex.

 <template #header.data-table-select="{ on , props }">
  <v-simple-checkbox
    aria-label="Select all"
    ref="headerCheckbox"
    v-bind="props"
    v-on="on"
    @keypress.enter="$refs.headerCheckbox.click()"
    @keypress.space="$refs.headerCheckbox.click()"
    tabindex="0"
  />
</template>
<template #item.data-table-select="{ item, isSelected, select, index }">
  <v-simple-checkbox
    aria-label="`Select ${item.full_name}`"
    :ref="`tableCheckbox-${index}`"
    :value="isSelected"
    @input="select($event)"
    @keypress.enter="$refs[`tableCheckbox-${index}`].click()"
    @keypress.space="$refs[`tableCheckbox-${index}`].click()"
    tabindex="0"
  />
</template>
VIXI0 commented 1 year ago

i really need this feature

VIXI0 commented 1 year ago

I have done a component extending v-data-table that is usable with a keyboard, change the page with left and right keys and reacted to keypress in a row allowing the developer to create quick action, when i got time I'm gonna publish the component to npm and yarn.

sadly im not sure if this will work on vuetify 3 image