RadioGroup:add accessibility

This commit is contained in:
maran 2017-07-26 21:24:23 +08:00 committed by 杨奕
parent 798bb8e75d
commit 7a84a3e44a
5 changed files with 90 additions and 7 deletions

View File

@ -6,6 +6,11 @@
{ 'is-active': value === label },
{ 'is-disabled': isDisabled }
]"
role="radio"
:aria-checked="value === label"
:aria-disabled="isDisabled"
:tabindex="tabIndex"
@keydown.space.stop.prevent="value = label"
>
<input
class="el-radio-button__orig-radio"
@ -13,7 +18,9 @@
type="radio"
v-model="value"
:name="name"
:disabled="isDisabled">
:disabled="isDisabled"
tabindex="-1"
>
<span class="el-radio-button__inner" :style="value === label ? activeStyle : null">
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
@ -62,6 +69,9 @@
},
isDisabled() {
return this.disabled || this._radioGroup.disabled;
},
tabIndex() {
return !this.isDisabled ? (this._radioGroup ? (this.value === this.label ? 0 : -1) : 0) : -1;
}
}
};

View File

@ -1,11 +1,21 @@
<template>
<div class="el-radio-group">
<div
class="el-radio-group"
role="radiogroup"
@keydown="handleKeydown"
>
<slot></slot>
</div>
</template>
<script>
import Emitter from 'element-ui/src/mixins/emitter';
const keyCode = Object.freeze({
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40
});
export default {
name: 'ElRadioGroup',
@ -20,6 +30,47 @@
textColor: String,
disabled: Boolean
},
mounted() {
// radioGroupTab
let radios = this.$el.querySelectorAll('[type=radio]');
if (![].some.call(radios, radio => radio.checked)) {
this.$el.querySelectorAll('[role=radio]')[0].tabIndex = 0;
}
},
methods: {
handleKeydown(e) { // radio
const target = e.target;
const className = target.nodeName === 'INPUT' ? '[type=radio]' : '[role=radio]';
const radios = this.$el.querySelectorAll(className);
const length = radios.length;
const index = [].indexOf.call(radios, target);
const roleRadios = this.$el.querySelectorAll('[role=radio]');
switch (e.keyCode) {
case keyCode.LEFT:
case keyCode.UP:
e.stopPropagation();
e.preventDefault();
if (index === 0) {
roleRadios[length - 1].click();
} else {
roleRadios[index - 1].click();
}
break;
case keyCode.RIGHT:
case keyCode.DOWN:
if (index === (length - 1)) {
e.stopPropagation();
e.preventDefault();
roleRadios[0].click();
} else {
roleRadios[index + 1].click();
}
break;
default:
break;
}
}
},
watch: {
value(value) {
this.$emit('change', value);

View File

@ -1,5 +1,12 @@
<template>
<label class="el-radio">
<label
class="el-radio"
role="radio"
:aria-checked="model === label"
:aria-disabled="isDisabled"
:tabindex="tabIndex"
@keydown.space.stop.prevent="model = label"
>
<span class="el-radio__input"
:class="{
'is-disabled': isDisabled,
@ -16,7 +23,9 @@
@focus="focus = true"
@blur="focus = false"
:name="name"
:disabled="isDisabled">
:disabled="isDisabled"
tabindex="-1"
>
</span>
<span class="el-radio__label">
<slot></slot>
@ -46,7 +55,6 @@
focus: false
};
},
computed: {
isGroup() {
let parent = this.$parent;
@ -60,12 +68,10 @@
}
return false;
},
model: {
get() {
return this.isGroup ? this._radioGroup.value : this.value;
},
set(val) {
if (this.isGroup) {
this.dispatch('ElRadioGroup', 'input', [val]);
@ -79,6 +85,9 @@
return this.isGroup
? this._radioGroup.disabled || this.disabled
: this.disabled;
},
tabIndex() {
return !this.isDisabled ? (this.isGroup ? (this.model === this.label ? 0 : -1) : 0) : -1;
}
}
};

View File

@ -75,6 +75,12 @@
box-shadow: none !important;
}
}
&:focus {
outline: none;
.el-radio-button__inner { /*获得焦点时 样式提醒*/
box-shadow: 0 0 1px 1px var(--radio-button-checked-border-color) !important;
}
}
&:last-child {
.el-radio-button__inner {
border-radius: 0 var(--border-radius-base) var(--border-radius-base) 0;

View File

@ -11,6 +11,13 @@
white-space: nowrap;
@utils-user-select none;
&:focus { /*获得焦点时 样式提醒*/
outline: none;
.el-radio__inner {
box-shadow: 0 0 1px 1px var(--radio-input-border-color-hover);
}
}
& + .el-radio {
margin-left: 15px;
}