mirror of https://github.com/ElemeFE/element
add accessibility for slider and fixbug for unittest
parent
9516c60c41
commit
0a597a949e
|
@ -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
|
||||||
|
|
|
@ -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.$refs.tooltip && this.$refs.tooltip.updatePopper();
|
this.$nextTick(() => {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
},
|
},
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue