Skip to content

Commit 390d401

Browse files
authored
为 Tabs 增加 WAI-ARIA 支持 (#235)
1 parent 781a89d commit 390d401

File tree

5 files changed

+51
-18
lines changed

5 files changed

+51
-18
lines changed

packages/veui-theme-one/components/tabs.less

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
transition: background-color .2s;
9999
}
100100

101+
&.focus-visible::after,
101102
&:hover::after {
102103
background-color: @veui-gray-color-3;
103104
}

packages/veui/demo/cases/Tabs.vue

+4-2
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@
7474
<p>当前序号 <code>{{index3 != null ? index3 + 1 : '已删光'}}</code></p>
7575
<veui-button @click="addTab1">添加 TAB</veui-button>
7676
<veui-tabs :active.sync="active2" :index.sync="index3">
77-
<template slot="tab-item-extra" slot-scope="props">
78-
<icon name="cross-small" v-if="props.removable && tabs1.length > 1" @click.native="removeTab1(props)"></icon>
77+
<template v-if="props.removable && tabs1.length > 1" slot="tab-item-extra" slot-scope="props">
78+
<button type="button" class="veui-tabs-item-remove" @click="removeTab1(props)">
79+
<icon name="cross-small"></icon>
80+
</button>
7981
</template>
8082
<veui-tab :label="tab.label"
8183
:name="tab.name"

packages/veui/src/components/Tabs/Tab.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div class="veui-tab" v-show="isActive">
2+
<div class="veui-tab" v-show="isActive" role="tabpanel" :aria-hidden="String(!isActive)">
33
<slot v-if="isInited || isActive"></slot>
44
</div>
55
</template>

packages/veui/src/components/Tabs/Tabs.vue

+44-15
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,41 @@
11
<template>
22
<div class="veui-tabs" :ui="ui">
3-
<div class="veui-tabs-menu" ref="menu">
3+
<div class="veui-tabs-menu" ref="menu" role="tablist">
44
<div class="veui-tabs-list" :class="{'veui-tabs-list-empty': items.length === 0}" ref="resizeContainer" v-resize="(e) => resizeHandler(e)">
55
<div class="veui-tabs-list-resizer">
66
<template v-for="(tab, index) in items">
7-
<div :key="tab.name" class="veui-tabs-item" :ref="`tab-${tab.name}`" :class="{
8-
'veui-tabs-item-disabled': tab.disabled,
9-
'veui-tabs-item-active': index === localIndex
10-
}">
7+
<div
8+
:key="tab.name"
9+
:ref="`tab-${tab.name}`"
10+
:class="{
11+
'veui-tabs-item': true,
12+
'veui-tabs-item-disabled': tab.disabled,
13+
'veui-tabs-item-active': index === localIndex
14+
}">
1115
<slot name="tab-item" v-bind="tab" :index="index">
12-
<veui-link v-if="tab.to" class="veui-tabs-item-label" :to="tab.to" :native="tab.native">{{ tab.label }}</veui-link>
13-
<button v-else class="veui-tabs-item-label" type="button" @click="!tab.disabled && setActive({index})">{{ tab.label }}</button>
14-
<button type="button" class="veui-tabs-item-remove"
15-
@click="$emit('remove', tab)">
16-
<slot name="tab-item-extra" v-bind="tab">
17-
<icon :name="icons.remove"
18-
v-if="tab.removable"></icon>
19-
</slot>
16+
<veui-link
17+
v-if="tab.to"
18+
class="veui-tabs-item-label"
19+
v-bind="ariaAttrs[index]"
20+
:to="tab.to"
21+
:native="tab.native">
22+
{{ tab.label }}
23+
</veui-link>
24+
<button
25+
v-else
26+
class="veui-tabs-item-label"
27+
v-bind="ariaAttrs[index]"
28+
type="button"
29+
@click="!tab.disabled && setActive({index})">
30+
{{ tab.label }}
2031
</button>
32+
<slot name="tab-item-extra" v-bind="tab">
33+
<button v-if="tab.removable" type="button" class="veui-tabs-item-remove"
34+
aria-label="删除"
35+
@click="$emit('remove', tab)">
36+
<icon :name="icons.remove"/>
37+
</button>
38+
</slot>
2139
</slot>
2240
</div>
2341
</template>
@@ -29,10 +47,11 @@
2947
:class="{'veui-tabs-extra-overflow': menuOverflow}">
3048
<button type="button" v-if="addable"
3149
class="veui-tabs-operator"
50+
aria-label="添加"
3251
@click="$emit('add')">
33-
<icon :name="icons.add"></icon><slot name="tabs-extra-text"><span>添加TAB</span></slot>
52+
<icon :name="icons.add"></icon><slot name="tabs-extra-text"><span>添加 Tab</span></slot>
3453
</button>
35-
<div class="veui-tabs-scroller" v-if="menuOverflow" ref="scroller">
54+
<div class="veui-tabs-scroller" v-if="menuOverflow" ref="scroller" aria-hidden="true">
3655
<button type="button" class="veui-tabs-scroller-left" @click="scroll('left')"><icon :name="icons.prev"></icon></button>
3756
<button type="button" class="veui-tabs-scroller-right" @click="scroll('right')"><icon :name="icons.next"></icon></button>
3857
</div>
@@ -93,6 +112,16 @@ export default {
93112
},
94113
tabNames () {
95114
return this.items.map(({ name }) => name)
115+
},
116+
ariaAttrs () {
117+
return this.items.map((tab, index) => {
118+
return {
119+
role: 'tab',
120+
'aria-selected': String(index === this.localIndex),
121+
'aria-setsize': this.items.length,
122+
'aria-posinset': index + 1
123+
}
124+
})
96125
}
97126
},
98127
methods: {

packages/veui/src/directives/resize.js

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ function attach (el, { value, arg, modifiers, oldValue }, vnode, oldVnode) {
99
obj.setAttribute('id', id)
1010
obj.setAttribute('type', 'text/html')
1111
obj.setAttribute('data', 'about:blank')
12+
obj.setAttribute('tabindex', '-1')
1213
assign(obj.style, {
1314
overflow: 'hidden',
1415
position: 'absolute',

0 commit comments

Comments
 (0)