Browse Source

fix: missing aria attributes + controls on tabset component

pull/5144/head
NGPixel 2 years ago
parent
commit
63ecb32494
No known key found for this signature in database GPG Key ID: 8FDA2F1757F60D63
1 changed files with 44 additions and 1 deletions
  1. 45
      client/themes/default/components/tabset.vue

45
client/themes/default/components/tabset.vue

@ -1,12 +1,16 @@
<template lang="pug">
.tabset.elevation-2
ul.tabset-tabs(ref='tabs')
ul.tabset-tabs(ref='tabs', role='tablist')
slot(name='tabs')
.tabset-content(ref='content')
slot(name='content')
</template>
<script>
import { customAlphabet } from 'nanoid/non-secure'
const nanoid = customAlphabet('1234567890abcdef', 10)
export default {
data() {
return {
@ -23,15 +27,19 @@ export default {
this.$refs.tabs.childNodes.forEach((node, idx) => {
if (idx === this.currentTab) {
node.className = 'is-active'
node.setAttribute('aria-selected', 'true')
} else {
node.className = ''
node.setAttribute('aria-selected', 'false')
}
})
this.$refs.content.childNodes.forEach((node, idx) => {
if (idx === this.currentTab) {
node.className = 'tabset-panel is-active'
node.removeAttribute('hidden')
} else {
node.className = 'tabset-panel'
node.setAttribute('hidden', '')
}
})
}
@ -53,10 +61,43 @@ export default {
this.setActiveTab()
const tabRefId = nanoid()
this.$refs.tabs.childNodes.forEach((node, idx) => {
node.setAttribute('id', `${tabRefId}-${idx}`)
node.setAttribute('role', 'tab')
node.setAttribute('aria-controls', `${tabRefId}-${idx}-tab`)
node.setAttribute('tabindex', '0')
node.addEventListener('click', ev => {
this.currentTab = [].indexOf.call(ev.target.parentNode.children, ev.target)
})
node.addEventListener('keydown', ev => {
if (ev.key === 'ArrowLeft' && idx > 0) {
this.currentTab = idx - 1
this.$refs.tabs.childNodes[idx - 1].focus()
} else if (ev.key === 'ArrowRight' && idx < this.$refs.tabs.childNodes.length - 1) {
this.currentTab = idx + 1
this.$refs.tabs.childNodes[idx + 1].focus()
} else if (ev.key === 'Enter' || ev.key === ' ') {
this.currentTab = idx
node.focus()
} else if (ev.key === 'Home') {
this.currentTab = 0
ev.preventDefault()
ev.target.parentNode.children[0].focus()
} else if (ev.key === 'End') {
this.currentTab = this.$refs.tabs.childNodes.length - 1
ev.preventDefault()
ev.target.parentNode.children[this.$refs.tabs.childNodes.length - 1].focus()
}
})
})
this.$refs.content.childNodes.forEach((node, idx) => {
node.setAttribute('id', `${tabRefId}-${idx}-tab`)
node.setAttribute('role', 'tabpanel')
node.setAttribute('aria-labelledby', `${tabRefId}-${idx}`)
node.setAttribute('tabindex', '0')
})
}
}
@ -106,7 +147,9 @@ export default {
background-color: #FFF;
margin-bottom: 0;
padding-bottom: 17px;
padding-top: 13px;
color: mc('blue', '700');
border-top: 3px solid mc('blue', '700');
@at-root .theme--dark & {
background-color: #292929;

Loading…
Cancel
Save