mirror of
https://gitee.com/ElemeFE/element.git
synced 2024-12-04 05:09:43 +08:00
RadioGroup:add accessibility
This commit is contained in:
parent
798bb8e75d
commit
7a84a3e44a
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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() {
|
||||
// 当radioGroup没有默认选项时,第一个可以选中Tab导航
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user