Parcourir la source

Merge branch 'dev' into fix/date-picker-input-event

cinwell.li il y a 8 ans
Parent
commit
a57fba12bd

+ 1 - 0
examples/docs/en-US/date-picker.md

@@ -256,6 +256,7 @@ Picking a date range is supported.
 | disabled | whether DatePicker is disabled | boolean | - | false |
 |size | size of Input | string | large/small/mini | — |
 | editable | whether the input is editable | boolean | - | true |
+| clearable | Whether to show clear button | boolean | - | true |
 | placeholder | placeholder | string | — | — |
 | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
 | format | format of the picker | string | year `yyyy` month `MM` day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd |

+ 1 - 0
examples/docs/en-US/datetime-picker.md

@@ -210,6 +210,7 @@ Select date and time in one picker.
 | readonly | whether DatePicker is read only | boolean | — | false |
 | disabled | whether DatePicker is disabled | boolean | - | false |
 | editable | whether the input is editable | boolean | - | true |
+| clearable | Whether to show clear button | boolean | - | true |
 |size | size of Input | string | large/small/mini | — |
 | placeholder | placeholder | string | — | — |
 | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |

+ 4 - 1
examples/docs/en-US/input.md

@@ -591,7 +591,10 @@ Search data from server-side.
 
 | Event Name | Description | Parameters |
 |----| ----| ----|
-|click | triggers when the icon inside Input is clicked | event object |
+|click | triggers when the icon inside Input is clicked | (event: Event) |
+| blur | triggers when the icon inside Input is blur | (event: Event) |
+| focus | triggers when the icon inside Input is focus | (event: Event) |
+| change | triggers when the icon inside Input value change | (value: string \| number) |
 
 ### Autocomplete Attributes
 

+ 2 - 1
examples/docs/en-US/time-picker.md

@@ -146,7 +146,8 @@ Can pick an arbitrary time range.
 | readonly | whether DatePicker is read only | boolean | — | false |
 | disabled | whether DatePicker is disabled | boolean | - | false |
 | editable | whether the input is editable | boolean | - | true |
-|size | size of Input | string | large/small/mini | — |
+| clearable | Whether to show clear button | boolean | - | true |
+| size | size of Input | string | large/small/mini | — |
 | placeholder | placeholder | string | — | — |
 | format | format of the picker | string | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |
 | value | value of the picker | date for Time Picker, and string for Time Select | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |

+ 1 - 0
examples/docs/zh-CN/date-picker.md

@@ -289,6 +289,7 @@
 | readonly | 完全只读 | boolean | — | false |
 | disabled | 禁用 | boolean | - | false |
 | editable | 文本框可输入 | boolean | - | true |
+| clearable | 是否显示清除按钮 | boolean | - | true |
 | size          | 输入框尺寸     | string          | large, small, mini  | — |
 | placeholder | 占位内容 | string | — | — |
 | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |

+ 1 - 0
examples/docs/zh-CN/datetime-picker.md

@@ -233,6 +233,7 @@
 | readonly | 完全只读 | boolean | — | false |
 | disabled | 禁用 | boolean | - | false |
 | editable | 文本框可输入 | boolean | - | true |
+| clearable | 是否显示清除按钮 | boolean | - | true |
 | size          | 输入框尺寸     | string          | large, small, mini  | — |
 | placeholder | 占位内容 | string | — | — |
 | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |

+ 4 - 3
examples/docs/zh-CN/input.md

@@ -759,9 +759,10 @@ export default {
 ### Input Events
 | 事件名称 | 说明 | 回调参数 |
 |---------|--------|---------|
-| click | 点击 Input 内的图标时触发 | event |
-| blur | 在 Input 失去焦点时触发 | event |
-| focus | 在 Input 或得焦点时触发 | event |
+| click | 点击 Input 内的图标时触发 | (event: Event) |
+| blur | 在 Input 失去焦点时触发 | (event: Event) |
+| focus | 在 Input 或得焦点时触发 | (event: Event) |
+| change | 在 Input 值改变时触发 | (value: string \| number) |
 
 ### Autocomplete Attributes
 

+ 1 - 0
examples/docs/zh-CN/time-picker.md

@@ -153,6 +153,7 @@
 | readonly | 完全只读 | boolean | — | false |
 | disabled | 禁用 | boolean | - | false |
 | editable | 文本框可输入 | boolean | - | true |
+| clearable | 是否显示清除按钮 | boolean | - | true |
 | size          | 输入框尺寸     | string          | large, small, mini  | — |
 | placeholder | 占位内容 | string | — | — |
 | format | 时间格式化(TimePicker) | string | 小时:`HH`,分:`mm`,秒:`ss` | 'HH:mm:ss' |

+ 8 - 4
packages/date-picker/src/picker.vue

@@ -187,6 +187,10 @@ export default {
     readonly: Boolean,
     placeholder: String,
     disabled: Boolean,
+    clearable: {
+      type: Boolean,
+      default: true
+    },
     popperClass: String,
     editable: {
       type: Boolean,
@@ -325,17 +329,17 @@ export default {
   methods: {
     handleMouseEnterIcon() {
       if (this.readonly || this.disabled) return;
-      if (!this.valueIsEmpty) {
+      if (!this.valueIsEmpty && this.clearable) {
         this.showClose = true;
       }
     },
 
     handleClickIcon() {
       if (this.readonly || this.disabled) return;
-      if (this.valueIsEmpty) {
-        this.pickerVisible = !this.pickerVisible;
-      } else {
+      if (this.showClose) {
         this.internalValue = '';
+      } else {
+        this.pickerVisible = !this.pickerVisible;
       }
     },
 

+ 32 - 29
packages/input/src/input.vue

@@ -33,7 +33,7 @@
         :min="min"
         :max="max"
         :form="form"
-        :value="value"
+        :value="currentValue"
         ref="input"
         @input="handleInput"
         @focus="handleFocus"
@@ -76,6 +76,13 @@
 
     mixins: [emitter],
 
+    data() {
+      return {
+        currentValue: this.value,
+        textareaStyle: {}
+      };
+    },
+
     props: {
       value: [String, Number],
       placeholder: String,
@@ -108,10 +115,23 @@
       min: {}
     },
 
+    computed: {
+      validating() {
+        return this.$parent.validateState === 'validating';
+      }
+    },
+
+    watch: {
+      'value'(val, oldValue) {
+        this.setCurrentValue(val);
+      }
+    },
+
     methods: {
       handleBlur(event) {
         this.$emit('blur', event);
         this.dispatch('ElFormItem', 'el.form.blur', [this.currentValue]);
+        this.currentValue = this.value;
       },
       inputSelect() {
         this.$refs.input.select();
@@ -130,46 +150,29 @@
         this.$emit('focus', event);
       },
       handleInput(event) {
-        this.currentValue = event.target.value;
+        this.setCurrentValue(event.target.value);
       },
       handleIconClick(event) {
         this.$emit('click', event);
+      },
+      setCurrentValue(value) {
+        if (value === this.currentValue) return;
+        this.$nextTick(_ => {
+          this.resizeTextarea();
+        });
+        this.currentValue = value;
+        this.$emit('input', value);
+        this.$emit('change', value);
+        this.dispatch('ElFormItem', 'el.form.change', [value]);
       }
     },
 
-    data() {
-      return {
-        currentValue: this.value,
-        textareaStyle: {}
-      };
-    },
-
     created() {
       this.$on('inputSelect', this.inputSelect);
     },
 
     mounted() {
       this.resizeTextarea();
-    },
-
-    computed: {
-      validating() {
-        return this.$parent.validateState === 'validating';
-      }
-    },
-
-    watch: {
-      'value'(val, oldValue) {
-        this.currentValue = val;
-      },
-      'currentValue'(val) {
-        this.$nextTick(_ => {
-          this.resizeTextarea();
-        });
-        this.$emit('input', val);
-        this.$emit('change', val);
-        this.dispatch('ElFormItem', 'el.form.change', [val]);
-      }
     }
   };
 </script>

+ 8 - 0
packages/menu/src/menu.vue

@@ -107,6 +107,14 @@
       },
       openActiveItemMenus() {
         let index = this.activeIndex;
+        // 选中用户指定的路由对应的menu
+        if (this.router) {
+          const userSpecifiedIndexs = Object
+                                       .keys(this.menuItems)
+                                       .filter(k => this.menuItems[k].route)
+                                       .filter(k => this.menuItems[k].route.path === this.$route.path);
+          userSpecifiedIndexs.length && (index = this.activeIndex = userSpecifiedIndexs[0]);
+        }
         if (!this.menuItems[index]) return;
         if (index && this.mode === 'vertical') {
           let indexPath = this.menuItems[index].indexPath;

+ 2 - 0
packages/table/src/table-body.js

@@ -95,6 +95,8 @@ export default {
       const newRow = rows[data.indexOf(newVal)];
       if (oldRow) {
         oldRow.classList.remove('current-row');
+      } else if (rows) {
+        [].forEach.call(rows, row => row.classList.remove('current-row'));
       }
       if (newRow) {
         newRow.classList.add('current-row');

+ 1 - 0
packages/theme-default/src/pagination.css

@@ -7,6 +7,7 @@
     white-space: nowrap;
     padding: 2px 5px;
     color: var(--pagination-color);
+    @utils-clearfix;
 
     span,
     button {

+ 2 - 2
packages/tree/src/tree-node.vue

@@ -133,12 +133,12 @@
         this.tree.$emit('current-change', store.currentNode ? store.currentNode.data : null, store.currentNode);
         this.tree.currentNode = this;
         if (this.tree.expandOnClickNode) {
-          this.handleExpandIconClick(event);
+          this.handleExpandIconClick();
         }
         this.tree.$emit('node-click', this.node.data, this.node, this);
       },
 
-      handleExpandIconClick(event) {
+      handleExpandIconClick() {
         if (this.expanded) {
           this.node.collapse();
         } else {

+ 25 - 0
test/unit/specs/date-picker.spec.js

@@ -91,6 +91,31 @@ describe('DatePicker', () => {
     }, DELAY);
   });
 
+  it('disabled clear value', done => {
+    vm = createVue({
+      template: `
+        <el-date-picker v-model="value" ref="compo" :clearable="false"></el-date-picker>
+      `,
+      data() {
+        return { value: '' };
+      }
+    }, true);
+    const input = vm.$el.querySelector('input');
+
+    input.focus();
+    setTimeout(_ => {
+      const $el = vm.$refs.compo.picker.$el;
+      $el.querySelector('td.available').click();
+      vm.$nextTick(_ => {
+        vm.$el.querySelector('.el-input__icon').click();
+        setTimeout(_ => {
+          expect(vm.value).to.be.exist;
+          done();
+        }, DELAY);
+      });
+    }, DELAY);
+  });
+
   it('reset', done => {
     vm = createVue({
       template: `

+ 54 - 0
test/unit/specs/input.spec.js

@@ -104,6 +104,7 @@ describe('Input', () => {
     }, true);
     expect(vm.$el.querySelector('.el-textarea__inner').getAttribute('rows')).to.be.equal('3');
   });
+
   it('autosize', done => {
     vm = createVue({
       template: `
@@ -143,4 +144,57 @@ describe('Input', () => {
       done();
     }, 200);
   });
+
+  describe('Input Events', () => {
+    it('event:focus & blur', done => {
+      vm = createVue({
+        template: `
+          <el-input
+            ref="input"
+            placeholder="请输入内容"
+            value="input">
+          </el-input>
+        `
+      }, true);
+
+      const spyFocus = sinon.spy();
+      const spyBlur = sinon.spy();
+
+      vm.$refs.input.$on('focus', spyFocus);
+      vm.$refs.input.$on('blur', spyBlur);
+      vm.$el.querySelector('input').focus();
+      vm.$el.querySelector('input').blur();
+
+      vm.$nextTick(_ => {
+        expect(spyFocus.calledOnce).to.be.true;
+        expect(spyBlur.calledOnce).to.be.true;
+        done();
+      });
+    });
+    it('event:change', done => {
+      vm = createVue({
+        template: `
+          <el-input
+            ref="input"
+            placeholder="请输入内容"
+            :value="input">
+          </el-input>
+        `,
+        data() {
+          return {
+            input: 'a'
+          };
+        }
+      }, true);
+
+      const spy = sinon.spy();
+      vm.$refs.input.$on('change', spy);
+      vm.input = 'b';
+
+      vm.$nextTick(_ => {
+        expect(spy.withArgs('b').calledOnce).to.be.true;
+        done();
+      });
+    });
+  });
 });

+ 12 - 0
test/unit/specs/pagination.spec.js

@@ -40,6 +40,18 @@ describe('Pagination', () => {
     expect(elm.querySelector('.el-pagination__total')).to.not.exist;
   });
 
+  it('layout: all in right, need clear float', () => {
+    vm = createTest(Pagination, {
+      layout: '->, prev, pager, next',
+      total: 100
+    }, true);
+    const elm = vm.$el;
+    let right_div = elm.querySelector('.el-pagination__rightwrapper');
+    expect(elm.clientHeight > 0 && right_div.clientHeight > 0).to.equal(true);
+    // elm 将来 padding 可能会变化, 所以使用 >= 来判定
+    expect(elm.clientHeight >= right_div.clientHeight).to.equal(true);
+  });
+
   it('custom slot', () => {
     vm = createVue({
       template: `