瀏覽代碼

DatePicker: support keyboard control (#6131)

* DatePicker: support keyboard control

* DatePicker: support keyboard control

* update test timeout

* fix space
Dreamacro 8 年之前
父節點
當前提交
97183e3bc6
共有 3 個文件被更改,包括 84 次插入3 次删除
  1. 56 3
      packages/date-picker/src/panel/date.vue
  2. 23 0
      packages/date-picker/src/picker/date-picker.js
  3. 5 0
      test/unit/karma.conf.js

+ 56 - 3
packages/date-picker/src/panel/date.vue

@@ -1,5 +1,5 @@
 <template>
-  <transition name="el-zoom-in-top" @after-leave="afterLeave">
+  <transition name="el-zoom-in-top" @after-enter="handleEnter" @after-leave="handleLeave">
     <div
       v-show="visible"
       :style="{
@@ -344,9 +344,62 @@
         }
       },
 
-      afterLeave() {
+      handleEnter() {
+        document.body.addEventListener('keydown', this.handleKeyDown);
+      },
+
+      handleLeave() {
         this.$refs.timepicker && this.$refs.timepicker.$emit('pick');
-        this.$emit('dodestroy');
+        this.$emit('dodestory');
+        document.body.removeEventListener('keydown', this.handleKeyDown);
+      },
+
+      handleKeyDown(e) {
+        const keyCode = e.keyCode;
+        const list = [38, 40, 37, 39];
+        if (this.visible && !this.timePickerVisible) {
+          if (list.indexOf(keyCode) !== -1) {
+            this.handleKeyControl(keyCode);
+            event.stopPropagation();
+            event.preventDefault();
+          }
+
+          if (keyCode === 13) {
+            this.confirm();
+            event.stopPropagation();
+            event.preventDefault();
+          }
+        }
+      },
+
+      handleKeyControl(keyCode) {
+        const mapping = {
+          'year': {
+            38: -4, 40: 4, 37: -1, 39: 1, offset: (date, step) => date.setFullYear(date.getFullYear() + step)
+          },
+          'month': {
+            38: -4, 40: 4, 37: -1, 39: 1, offset: (date, step) => date.setMonth(date.getMonth() + step)
+          },
+          'week': {
+            38: -1, 40: 1, 37: -1, 39: 1, offset: (date, step) => date.setDate(date.getDate() + step * 7)
+          },
+          'day': {
+            38: -7, 40: 7, 37: -1, 39: 1, offset: (date, step) => date.setDate(date.getDate() + step)
+          }
+        };
+        const mode = this.selectionMode;
+        const year = 3.1536e10;
+        const now = this.date.getTime();
+        const newDate = new Date(this.date.getTime());
+        while (Math.abs(now - newDate.getTime()) <= year) {
+          const map = mapping[mode];
+          map.offset(newDate, map[keyCode]);
+          if (typeof this.disabledDate === 'function' && this.disabledDate(newDate)) {
+            continue;
+          }
+          this.date = newDate;
+          break;
+        }
       }
     },
 

+ 23 - 0
packages/date-picker/src/picker/date-picker.js

@@ -35,5 +35,28 @@ export default {
 
   created() {
     this.panel = getPanel(this.type);
+  },
+
+  methods: {
+    handleKeydown(event) {
+      const keyCode = event.keyCode;
+
+      // TAB or ESC or Enter
+      if (keyCode === 9 || keyCode === 27 || keyCode === 13) {
+        this.pickerVisible = false;
+        event.stopPropagation();
+        this.currentValue = this.picker.date;
+        this.$refs.reference.$refs.input.blur();
+        return;
+      }
+
+      const list = [38, 40, 37, 39];
+      if (list.indexOf(keyCode) !== -1) {
+        if (this.type === 'daterange' || this.type === 'datetimerange') return;
+        this.picker.handleKeyControl(keyCode);
+        event.stopPropagation();
+        return;
+      }
+    }
   }
 };

+ 5 - 0
test/unit/karma.conf.js

@@ -26,6 +26,11 @@ module.exports = function(config) {
         { type: 'lcov', subdir: '.' },
         { type: 'text-summary' }
       ]
+    },
+    client: {
+      mocha: {
+        timeout: 4000
+      }
     }
   });
 };