TimePicker: support keyboard control (#6050)

* TimePicker: support keyboard control

* fix time-range

* fix timeformat
pull/6189/head
Dreamacro 2017-07-30 16:23:01 +08:00 committed by 杨奕
parent 5c2589677a
commit de28477064
4 changed files with 124 additions and 4 deletions

View File

@ -129,7 +129,8 @@
hoursPrivate: 0,
minutesPrivate: 0,
secondsPrivate: 0,
selectableRange: []
selectableRange: [],
currentScrollbar: null
};
},
@ -162,6 +163,7 @@
} else if (type === 'seconds') {
this.$emit('select-range', 6, 8);
}
this.currentScrollbar = type;
},
bindScrollEvent() {
@ -188,6 +190,35 @@
ajustElTop(type, value) {
this[`${type}El`].scrollTop = Math.max(0, (value - 2.5) * 32 + 80);
},
scrollDown(step) {
if (!this.currentScrollbar) {
this.emitSelectRange('hours');
}
const label = this.currentScrollbar;
const hoursList = this.hoursList;
let now = this[label];
if (this.currentScrollbar === 'hours') {
let total = Math.abs(step);
step = step > 0 ? 1 : -1;
let length = hoursList.length;
while (length-- && total) {
now = (now + step + hoursList.length) % hoursList.length;
if (hoursList[now]) {
continue;
}
total--;
}
if (hoursList[now]) return;
} else {
now = (now + step + 60) % 60;
}
this.$emit('change', { [label]: now });
this.ajustElTop(label.slice(0, -1), now);
}
}
};

View File

@ -89,6 +89,14 @@
computed: {
showSeconds() {
return (this.format || '').indexOf('ss') !== -1;
},
offset() {
return this.showSeconds ? 11 : 8;
},
spinner() {
return this.selectionRange[0] < this.offset ? this.$refs.minSpinner : this.$refs.maxSpinner;
}
},
@ -110,7 +118,8 @@
minSeconds: time.minTime.getSeconds(),
format: 'HH:mm:ss',
visible: false,
width: 0
width: 0,
selectionRange: [0, 2]
};
},
@ -118,6 +127,12 @@
value(newVal) {
this.panelCreated();
this.$nextTick(_ => this.ajustScrollTop());
},
visible(val) {
if (val) {
this.$nextTick(() => this.$refs.minSpinner.emitSelectRange('hours'));
}
}
},
@ -194,10 +209,12 @@
setMinSelectionRange(start, end) {
this.$emit('select-range', start, end);
this.selectionRange = [start, end];
},
setMaxSelectionRange(start, end) {
this.$emit('select-range', start + 11, end + 11);
this.$emit('select-range', start + this.offset, end + this.offset);
this.selectionRange = [start + this.offset, end + this.offset];
},
handleConfirm(visible = false, first = false) {
@ -214,6 +231,23 @@
ajustScrollTop() {
this.$refs.minSpinner.ajustScrollTop();
this.$refs.maxSpinner.ajustScrollTop();
},
scrollDown(step) {
this.spinner.scrollDown(step);
},
changeSelectionRange(step) {
const list = this.showSeconds ? [0, 3, 6, 11, 14, 17] : [0, 3, 8, 11];
const mapping = ['hours', 'minutes'].concat(this.showSeconds ? ['seconds'] : []);
const index = list.indexOf(this.selectionRange[0]);
const next = (index + step + list.length) % list.length;
const half = list.length / 2;
if (next < half) {
this.$refs.minSpinner.emitSelectRange(mapping[next]);
} else {
this.$refs.maxSpinner.emitSelectRange(mapping[next - half]);
}
}
},

View File

@ -54,6 +54,9 @@
watch: {
visible(val) {
this.currentVisible = val;
if (val) {
this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'));
}
},
pickerWidth(val) {
@ -92,7 +95,8 @@
selectableRange: [],
currentDate: this.$options.defaultValue || this.date || new Date(),
currentVisible: this.visible || false,
width: this.pickerWidth || 0
width: this.pickerWidth || 0,
selectionRange: [0, 2]
};
},
@ -130,6 +134,7 @@
setSelectionRange(start, end) {
this.$emit('select-range', start, end);
this.selectionRange = [start, end];
},
handleConfirm(visible = false, first) {
@ -140,6 +145,18 @@
ajustScrollTop() {
return this.$refs.spinner.ajustScrollTop();
},
scrollDown(step) {
this.$refs.spinner.scrollDown(step);
},
changeSelectionRange(step) {
const list = [0, 3].concat(this.showSeconds ? [6] : []);
const mapping = ['hours', 'minutes'].concat(this.showSeconds ? ['seconds'] : []);
const index = list.indexOf(this.selectionRange[0]);
const next = (index + step + list.length) % list.length;
this.$refs.spinner.emitSelectRange(mapping[next]);
}
},

View File

@ -34,5 +34,43 @@ export default {
created() {
this.type = this.isRange ? 'timerange' : 'time';
this.panel = this.isRange ? TimeRangePanel : TimePanel;
},
methods: {
handleKeydown(event) {
const keyCode = event.keyCode;
// TAB or ESC
if (keyCode === 9 || keyCode === 27) {
this.pickerVisible = false;
event.stopPropagation();
return;
}
const mapping = { 38: -1, 40: 1, 37: -1, 39: 1 };
// Left or Right
if (keyCode === 37 || keyCode === 39) {
const step = mapping[keyCode];
this.picker.changeSelectionRange(step);
event.preventDefault();
return;
}
// Up or Down
if (keyCode === 38 || keyCode === 40) {
const step = mapping[keyCode];
this.picker.scrollDown(step);
event.preventDefault();
return;
}
if (keyCode === 13) {
this.picker.handleConfirm();
this.$refs.reference.$refs.input.blur();
event.preventDefault();
return;
}
}
}
};