add accessibility for slider and fixbug for unittest

pull/7327/head
maran 2017-09-26 18:01:12 +08:00 committed by 杨奕
parent 9516c60c41
commit 0a597a949e
5 changed files with 44 additions and 8 deletions

View File

@ -237,6 +237,7 @@
| range | 是否为范围选择 | boolean | — | false | | range | 是否为范围选择 | boolean | — | false |
| vertical | 是否竖向模式 | boolean | — | false | | vertical | 是否竖向模式 | boolean | — | false |
| height | Slider 高度,竖向模式时必填 | String | — | — | | height | Slider 高度,竖向模式时必填 | String | — | — |
| label | label for screen reader | String | — | — |
| debounce | 输入时的去抖延迟,毫秒,仅在`show-input`等于true时有效 | number | — | 300 | | debounce | 输入时的去抖延迟,毫秒,仅在`show-input`等于true时有效 | number | — | 300 |
### Events ### Events

View File

@ -6,7 +6,15 @@
@mousedown="onButtonDown" @mousedown="onButtonDown"
:class="{ 'hover': hovering, 'dragging': dragging }" :class="{ 'hover': hovering, 'dragging': dragging }"
:style="wrapperStyle" :style="wrapperStyle"
ref="button"> ref="button"
tabindex="0"
@focus="handleMouseEnter"
@blur="handleMouseLeave"
@keydown.left="onLeftKeyDown"
@keydown.right="onRightKeyDown"
@keydown.down.prevent="onLeftKeyDown"
@keydown.up.prevent="onRightKeyDown"
>
<el-tooltip placement="top" ref="tooltip" :disabled="!showTooltip"> <el-tooltip placement="top" ref="tooltip" :disabled="!showTooltip">
<span slot="content">{{ formatValue }}</span> <span slot="content">{{ formatValue }}</span>
<div class="el-slider__button" :class="{ 'hover': hovering, 'dragging': dragging }"></div> <div class="el-slider__button" :class="{ 'hover': hovering, 'dragging': dragging }"></div>
@ -125,7 +133,16 @@
window.addEventListener('mouseup', this.onDragEnd); window.addEventListener('mouseup', this.onDragEnd);
window.addEventListener('contextmenu', this.onDragEnd); window.addEventListener('contextmenu', this.onDragEnd);
}, },
onLeftKeyDown() {
if (this.disabled) return;
this.newPosition = parseFloat(this.currentPosition) - this.step / (this.max - this.min) * 100;
this.setPosition(this.newPosition);
},
onRightKeyDown() {
if (this.disabled) return;
this.newPosition = parseFloat(this.currentPosition) + this.step / (this.max - this.min) * 100;
this.setPosition(this.newPosition);
},
onDragStart(event) { onDragStart(event) {
this.dragging = true; this.dragging = true;
this.isClick = true; this.isClick = true;
@ -187,7 +204,9 @@
let value = steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min; let value = steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min;
value = parseFloat(value.toFixed(this.precision)); value = parseFloat(value.toFixed(this.precision));
this.$emit('input', value); this.$emit('input', value);
this.$nextTick(() => {
this.$refs.tooltip && this.$refs.tooltip.updatePopper(); this.$refs.tooltip && this.$refs.tooltip.updatePopper();
});
if (!this.dragging && this.value !== this.oldValue) { if (!this.dragging && this.value !== this.oldValue) {
this.oldValue = this.value; this.oldValue = this.value;
} }

View File

@ -1,6 +1,12 @@
<template> <template>
<div class="el-slider" <div class="el-slider"
:class="{ 'is-vertical': vertical, 'el-slider--with-input': showInput }"> :class="{ 'is-vertical': vertical, 'el-slider--with-input': showInput }"
role="slider"
:aria-valuemin="min"
:aria-valuemax="max"
:aria-orientation="vertical ? 'vertical': 'horizontal'"
:aria-disabled="disabled"
>
<el-input-number <el-input-number
v-model="firstValue" v-model="firstValue"
v-if="showInput && !range" v-if="showInput && !range"
@ -107,6 +113,9 @@
debounce: { debounce: {
type: Number, type: Number,
default: 300 default: 300
},
label: {
type: String
} }
}, },
@ -317,6 +326,7 @@
}, },
mounted() { mounted() {
let valuetext;
if (this.range) { if (this.range) {
if (Array.isArray(this.value)) { if (Array.isArray(this.value)) {
this.firstValue = Math.max(this.min, this.value[0]); this.firstValue = Math.max(this.min, this.value[0]);
@ -326,6 +336,7 @@
this.secondValue = this.max; this.secondValue = this.max;
} }
this.oldValue = [this.firstValue, this.secondValue]; this.oldValue = [this.firstValue, this.secondValue];
valuetext = `${this.firstValue}-${this.secondValue}`;
} else { } else {
if (typeof this.value !== 'number' || isNaN(this.value)) { if (typeof this.value !== 'number' || isNaN(this.value)) {
this.firstValue = this.min; this.firstValue = this.min;
@ -333,7 +344,13 @@
this.firstValue = Math.min(this.max, Math.max(this.min, this.value)); this.firstValue = Math.min(this.max, Math.max(this.min, this.value));
} }
this.oldValue = this.firstValue; this.oldValue = this.firstValue;
valuetext = this.firstValue;
} }
this.$el.setAttribute('aria-valuetext', valuetext);
// label screen reader
this.$el.setAttribute('aria-label', this.label ? this.label : `slider between ${this.min} and ${this.max}`);
this.resetSize(); this.resetSize();
window.addEventListener('resize', this.resetSize); window.addEventListener('resize', this.resetSize);
}, },

View File

@ -1,4 +1,4 @@
import { createVue, destroyVM, triggerEvent } from '../util'; import { createVue, destroyVM, triggerEvent, triggerClick } from '../util';
describe('Cascader', () => { describe('Cascader', () => {
let vm; let vm;
@ -355,7 +355,6 @@ describe('Cascader', () => {
vm.$el.click(); vm.$el.click();
setTimeout(_ => { setTimeout(_ => {
expect(document.body.querySelector('.el-cascader-menus')).to.be.exist; expect(document.body.querySelector('.el-cascader-menus')).to.be.exist;
const menu = vm.$refs.cascader.menu; const menu = vm.$refs.cascader.menu;
const menuElm = menu.$el; const menuElm = menu.$el;
const item1 = menuElm.children[1].querySelector('.el-cascader-menu__item'); const item1 = menuElm.children[1].querySelector('.el-cascader-menu__item');
@ -366,8 +365,7 @@ describe('Cascader', () => {
expect(item1.classList.contains('is-active')).to.be.true; expect(item1.classList.contains('is-active')).to.be.true;
expect(item2.classList.contains('is-active')).to.be.true; expect(item2.classList.contains('is-active')).to.be.true;
expect(item3.classList.contains('is-active')).to.be.true; expect(item3.classList.contains('is-active')).to.be.true;
triggerClick(document, 'mouseup');
document.body.click();
setTimeout(_ => { setTimeout(_ => {
expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none'); expect(document.body.querySelector('.el-cascader-menus').style.display).to.be.equal('none');
done(); done();

View File

@ -19,6 +19,7 @@ const createElm = function() {
* @param {Object} vm * @param {Object} vm
*/ */
exports.destroyVM = function(vm) { exports.destroyVM = function(vm) {
vm.$destroy && vm.$destroy();
vm.$el && vm.$el &&
vm.$el.parentNode && vm.$el.parentNode &&
vm.$el.parentNode.removeChild(vm.$el); vm.$el.parentNode.removeChild(vm.$el);