소스 검색

Merge branch 'dev' into carbon

# Conflicts:
#	packages/date-picker/src/panel/time.vue
Leopoldthecoder 8 년 전
부모
커밋
43ecb8818c

+ 9 - 0
CHANGELOG.en-US.md

@@ -1,5 +1,14 @@
 ## Changelog
 
+### 1.4.4
+
+*2017-09-05*
+
+- Fixed all months disabled in DatePicker month view when `disabledDate` is set, #6768 @qingdengyue
+- Added `debounce` attribute for Slider, #6820 @langgo
+- Fixed value of Pagination jumper can be bigger than the total page count, #6842 @huguangju
+- Fixed TimePicker's focus slipping away when selecting hour to 23 with mouse scroll, #6719 @qingdengyue
+
 ### 1.4.3
 
 *2017-08-25*

+ 8 - 0
CHANGELOG.zh-CN.md

@@ -1,5 +1,13 @@
 ## 更新日志
 
+### 1.4.4
+*2017-09-05*
+
+- 修复设置了 `disabledDate` 的 DatePicker 在月视图下全部不可选的问题,#6768 @qingdengyue
+- Slider 新增 `debounce` 属性,#6820 @langgo
+- 修复 Pagination 的 jumper 中可以输入比最大页数更大的数字的问题,#6842 @huguangju
+- 修复 TimePicker 的小时数难以通过滚动的方式选中 23 时的问题,#6719 @qingdengyue
+
 ### 1.4.3
 *2017-08-25*
 

+ 1 - 0
examples/docs/en-US/slider.md

@@ -213,6 +213,7 @@ Selecting a range of values is supported.
 | range | whether to select a range | boolean | — | false |
 | vertical | vertical mode | boolean | — | false |
 | height | Slider height, required in vertical mode | String | — | — |
+|debounce| debounce delay when typing, in millisecond, works when `show-input` is true | number | — | 300 |
 
 ## Events
 | Event Name | Description | Parameters |

+ 1 - 0
examples/docs/en-US/tooltip.md

@@ -213,3 +213,4 @@ Disabled form elements are not supported in tooltip, see more information at [MD
 | manual | whether to control Tooltip manually. `mouseenter` and `mouseleave` won't have effects if set to `true` | boolean | — | false |
 |  popper-class  |  custom class name for Tooltip's popper | string | — | — |
 | enterable | whether the mouse can enter the tooltip | Boolean | — | true |
+| hide-after | timeout in milliseconds to hide tooltip | number | — | 0 |

+ 1 - 0
examples/docs/zh-CN/slider.md

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

+ 1 - 1
examples/docs/zh-CN/tree.md

@@ -935,7 +935,7 @@
 | --------------------- | ---------------------------------------- | --------------------------- | ---- | ----- |
 | data                  | 展示数据                                     | array                       | —    | —     |
 | empty-text            | 内容为空的时候展示的文本                             | String                      | —    | —     |
-| node-key              | 每个树节点用来作为唯一标识的属性,整树应该是唯一的               | String                      | —    | —     |
+| node-key              | 每个树节点用来作为唯一标识的属性,整树应该是唯一的               | String                      | —    | —     |
 | props                 | 配置选项,具体看下表                               | object                      | —    | —     |
 | load                  | 加载子树数据的方法                                | function(node, resolve)     | —    | —     |
 | render-content        | 树节点的内容区的渲染 Function                      | Function(h, { node }        | —    | —     |

+ 1 - 1
examples/versions.json

@@ -1 +1 @@
-{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.3":"1.4"}
+{"1.0.9":"1.0","1.1.6":"1.1","1.2.9":"1.2","1.3.7":"1.3","1.4.4":"1.4"}

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "element-ui",
-  "version": "1.4.3",
+  "version": "1.4.4",
   "description": "A Component Library for Vue.js.",
   "main": "lib/element-ui.common.js",
   "files": [

+ 2 - 8
packages/date-picker/src/basic/month-table.vue

@@ -78,18 +78,12 @@
           while (date < nextMonth) {
             if (this.disabledDate(date)) {
               date = new Date(date.getTime() + 8.64e7);
+              flag = true;
             } else {
+              flag = false;
               break;
             }
           }
-          // There is a bug of Chrome.
-          // For example:
-          // var date = new Date('1988-04-01 00:00:00') Fri Apr 01 1988 00:00:00 GMT+0800 (CST)
-          // date.setMonth(4) Sun May 01 1988 00:00:00 GMT+0900 (CDT)
-          // Sometimes the time zone will change.
-          if (date - nextMonth < 8.64e7) {
-            flag = true;
-          }
         }
 
         style.disabled = flag;

+ 14 - 1
packages/date-picker/src/panel/time.vue

@@ -56,6 +56,9 @@
       visible(val) {
         this.currentVisible = val;
         if (val) {
+          this.oldHours = this.hours;
+          this.oldMinutes = this.minutes;
+          this.oldSeconds = this.seconds;
           this.$nextTick(() => this.$refs.spinner.emitSelectRange('hours'));
         }
       },
@@ -98,6 +101,9 @@
         hours: 0,
         minutes: 0,
         seconds: 0,
+        oldHours: 0,
+        oldMinutes: 0,
+        oldSeconds: 0,
         selectableRange: [],
         currentDate: this.$options.defaultValue || this.date || new Date(),
         currentVisible: this.visible || false,
@@ -119,7 +125,14 @@
       },
 
       handleCancel() {
-        this.$emit('pick');
+        this.currentDate.setHours(this.oldHours);
+        this.currentDate.setMinutes(this.oldMinutes);
+        this.currentDate.setSeconds(this.oldSeconds);
+        this.hours = this.currentDate.getHours();
+        this.minutes = this.currentDate.getMinutes();
+        this.seconds = this.currentDate.getSeconds();
+        const date = new Date(limitRange(this.currentDate, this.selectableRange, 'HH:mm:ss'));
+        this.$emit('pick', date);
       },
 
       handleChange(date) {

+ 9 - 6
packages/dropdown/src/dropdown.vue

@@ -45,7 +45,8 @@
     data() {
       return {
         timeout: null,
-        visible: false
+        visible: false,
+        triggerElm: null
       };
     },
 
@@ -63,37 +64,39 @@
 
     methods: {
       show() {
+        if (this.triggerElm.disabled) return;
         clearTimeout(this.timeout);
         this.timeout = setTimeout(() => {
           this.visible = true;
         }, 250);
       },
       hide() {
+        if (this.triggerElm.disabled) return;
         clearTimeout(this.timeout);
         this.timeout = setTimeout(() => {
           this.visible = false;
         }, 150);
       },
       handleClick() {
+        if (this.triggerElm.disabled) return;
         this.visible = !this.visible;
       },
       initEvent() {
         let { trigger, show, hide, handleClick, splitButton } = this;
-        let triggerElm = splitButton
+        this.triggerElm = splitButton
           ? this.$refs.trigger.$el
           : this.$slots.default[0].elm;
 
-        if (triggerElm.disabled) return;
         if (trigger === 'hover') {
-          triggerElm.addEventListener('mouseenter', show);
-          triggerElm.addEventListener('mouseleave', hide);
+          this.triggerElm.addEventListener('mouseenter', show);
+          this.triggerElm.addEventListener('mouseleave', hide);
 
           let dropdownElm = this.$slots.dropdown[0].elm;
 
           dropdownElm.addEventListener('mouseenter', show);
           dropdownElm.addEventListener('mouseleave', hide);
         } else if (trigger === 'click') {
-          triggerElm.addEventListener('click', handleClick);
+          this.triggerElm.addEventListener('click', handleClick);
         }
       },
       handleMenuItemClick(command, instance) {

+ 11 - 11
packages/loading/src/index.js

@@ -19,21 +19,21 @@ LoadingConstructor.prototype.originalPosition = '';
 LoadingConstructor.prototype.originalOverflow = '';
 
 LoadingConstructor.prototype.close = function() {
-  if (this.fullscreen && this.originalOverflow !== 'hidden') {
-    document.body.style.overflow = this.originalOverflow;
-  }
-  if (this.fullscreen || this.body) {
-    document.body.style.position = this.originalPosition;
-  } else {
-    this.target.style.position = this.originalPosition;
-  }
   if (this.fullscreen) {
     fullscreenLoading = undefined;
   }
   this.$on('after-leave', _ => {
-    this.$el &&
-    this.$el.parentNode &&
-    this.$el.parentNode.removeChild(this.$el);
+    if (this.fullscreen && this.originalOverflow !== 'hidden') {
+      document.body.style.overflow = this.originalOverflow;
+    }
+    if (this.fullscreen || this.body) {
+      document.body.style.position = this.originalPosition;
+    } else {
+      this.target.style.position = this.originalPosition;
+    }
+    if (this.$el && this.$el.parentNode) {
+      this.$el.parentNode.removeChild(this.$el);
+    }
     this.$destroy();
   });
   this.visible = false;

+ 11 - 1
packages/pagination/src/pagination.js

@@ -192,16 +192,25 @@ export default {
         handleFocus(event) {
           this.oldValue = event.target.value;
         },
+        handleBlur({ target }) {
+          this.reassignMaxValue(target);
+        },
         handleKeyUp(event) {
           const key = event.key || '';
           const keyCode = event.keyCode || '';
           if ((key && key === 'Enter') || (keyCode && keyCode === 13)) {
+            this.reassignMaxValue(event.target);
             this.handleChange({ target: event.target });
           }
         },
         handleChange({ target }) {
           this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(target.value);
           this.oldValue = null;
+        },
+        reassignMaxValue(target) {
+          if (+target.value > this.$parent.internalPageCount) {
+            target.value = this.$parent.internalPageCount;
+          }
         }
       },
 
@@ -213,11 +222,12 @@ export default {
               class="el-pagination__editor"
               type="number"
               min={ 1 }
-              max={ this.internalPageCount }
+              max={ this.$parent.internalPageCount }
               value={ this.$parent.internalCurrentPage }
               domProps-value={ this.$parent.internalCurrentPage }
               on-change={ this.handleChange }
               on-focus={ this.handleFocus }
+              on-blur={ this.handleBlur }
               on-keyup={ this.handleKeyUp }
               number/>
             { this.t('el.pagination.pageClassifier') }

+ 10 - 8
packages/rate/src/main.vue

@@ -32,7 +32,6 @@
     data() {
       return {
         classMap: {},
-        colorMap: {},
         pointerAtLeftHalf: true,
         currentValue: this.value,
         hoverIndex: -1
@@ -159,6 +158,16 @@
         return this.getValueFromMap(this.currentValue, this.classMap);
       },
 
+      colorMap() {
+        return {
+          lowColor: this.colors[0],
+          mediumColor: this.colors[1],
+          highColor: this.colors[2],
+          voidColor: this.voidColor,
+          disabledVoidColor: this.disabledVoidColor
+        };
+      },
+
       activeColor() {
         return this.getValueFromMap(this.currentValue, this.colorMap);
       },
@@ -274,13 +283,6 @@
         voidClass: this.voidIconClass,
         disabledVoidClass: this.disabledVoidIconClass
       };
-      this.colorMap = {
-        lowColor: this.colors[0],
-        mediumColor: this.colors[1],
-        highColor: this.colors[2],
-        voidColor: this.voidColor,
-        disabledVoidColor: this.disabledVoidColor
-      };
     }
   };
 </script>

+ 2 - 3
packages/select/src/select.vue

@@ -660,8 +660,7 @@
       },
 
       getValueKey(item) {
-        const type = typeof item.value;
-        if (type === 'number' || type === 'string') {
+        if (Object.prototype.toString.call(item.value).toLowerCase() !== '[object object]') {
           return item.value;
         } else {
           return getValueByPath(item.value, this.valueKey);
@@ -677,7 +676,6 @@
       if (!this.multiple && Array.isArray(this.value)) {
         this.$emit('input', '');
       }
-      this.setSelected();
 
       this.debouncedOnInputChange = debounce(this.debounce, () => {
         this.onInputChange();
@@ -700,6 +698,7 @@
           this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width;
         }
       });
+      this.setSelected();
     },
 
     beforeDestroy() {

+ 5 - 0
packages/slider/src/main.vue

@@ -12,6 +12,7 @@
       :controls="showInputControls"
       :min="min"
       :max="max"
+      :debounce="debounce"
       size="small">
     </el-input-number>
     <div class="el-slider__runway"
@@ -102,6 +103,10 @@
       },
       height: {
         type: String
+      },
+      debounce: {
+        type: Number,
+        default: 300
       }
     },
 

+ 1 - 1
packages/table/src/table-header.js

@@ -102,7 +102,7 @@ export default {
                     on-mouseout={ this.handleMouseOut }
                     on-mousedown={ ($event) => this.handleMouseDown($event, column) }
                     on-click={ ($event) => this.handleHeaderClick($event, column) }
-                    class={ [column.id, column.order, column.headerAlign, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex, columns) ? 'is-hidden' : '', !column.children ? 'is-leaf' : '', column.labelClassName] }>
+                    class={ [column.id, column.order, column.headerAlign, column.className || '', rowIndex === 0 && this.isCellHidden(cellIndex, columns) ? 'is-hidden' : '', !column.children ? 'is-leaf' : '', column.labelClassName, column.sortable ? 'is-sortable' : ''] }>
                     <div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : '', column.labelClassName] }>
                     {
                       column.renderHeader

+ 1 - 1
packages/theme-default/package.json

@@ -1,6 +1,6 @@
 {
   "name": "element-theme-default",
-  "version": "1.4.3",
+  "version": "1.4.4",
   "description": "Element component default theme.",
   "main": "lib/index.css",
   "style": "lib/index.css",

+ 4 - 0
packages/theme-default/src/table.css

@@ -136,6 +136,10 @@
       border-bottom: 1px solid var(--table-border-color);
     }
 
+    & th.is-sortable {
+      cursor: pointer;
+    }
+
     @modifier border {
       & th, td {
         border-right: 1px solid var(--table-border-color);

+ 26 - 1
packages/tooltip/src/main.js

@@ -39,9 +39,20 @@ export default {
     enterable: {
       type: Boolean,
       default: true
+    },
+    hideAfter: {
+      type: Number,
+      default: 0
     }
   },
 
+  data() {
+    return {
+      timeoutPending: null,
+      handlerAdded: false
+    };
+  },
+
   beforeCreate() {
     if (this.$isServer) return;
 
@@ -77,7 +88,7 @@ export default {
     if (!this.$slots.default || !this.$slots.default.length) return this.$slots.default;
 
     const vnode = getFirstComponentChild(this.$slots.default);
-    if (!vnode) return vnode;
+    if (!vnode || this.handlerAdded) return vnode;
     const data = vnode.data = vnode.data || {};
     const on = vnode.data.on = vnode.data.on || {};
     const nativeOn = vnode.data.nativeOn = vnode.data.nativeOn || {};
@@ -97,6 +108,7 @@ export default {
 
   methods: {
     addEventHandle(old, fn) {
+      this.handlerAdded = true;
       return old ? Array.isArray(old) ? old.concat(fn) : [old, fn] : fn;
     },
 
@@ -111,15 +123,28 @@ export default {
       this.timeout = setTimeout(() => {
         this.showPopper = true;
       }, this.openDelay);
+
+      if (this.hideAfter > 0) {
+        this.timeoutPending = setTimeout(() => {
+          this.showPopper = false;
+        }, this.hideAfter);
+      }
     },
 
     handleClosePopper() {
       if (this.enterable && this.expectedState || this.manual) return;
       clearTimeout(this.timeout);
+
+      if (this.timeoutPending) {
+        clearTimeout(this.timeoutPending);
+      }
       this.showPopper = false;
     },
 
     setExpectedState(expectedState) {
+      if (expectedState === false) {
+        clearTimeout(this.timeoutPending);
+      }
       this.expectedState = expectedState;
     }
   }

+ 1 - 1
packages/tree/src/model/node.js

@@ -118,7 +118,7 @@ export default class Node {
       this.expand(null, store.autoExpandParent);
     }
 
-    if (key && store.currentNodeKey && this.key === store.currentNodeKey) {
+    if (key && store.currentNodeKey !== undefined && this.key === store.currentNodeKey) {
       store.currentNode = this;
     }
 

+ 1 - 1
src/index.js

@@ -168,7 +168,7 @@ if (typeof window !== 'undefined' && window.Vue) {
 };
 
 module.exports = {
-  version: '1.4.3',
+  version: '1.4.4',
   locale: locale.use,
   i18n: locale.i18n,
   install,

+ 43 - 43
src/locale/lang/es.js

@@ -2,56 +2,56 @@ export default {
   el: {
     colorpicker: {
       confirm: 'Confirmar',
-      clear: 'Limpiar'
+      clear: 'Despejar'
     },
     datepicker: {
       now: 'Ahora',
       today: 'Hoy',
       cancel: 'Cancelar',
-      clear: 'Limpiar',
+      clear: 'Despejar',
       confirm: 'Confirmar',
       selectDate: 'Seleccionar fecha',
       selectTime: 'Seleccionar hora',
-      startDate: 'Fecha de Inicio',
-      startTime: 'Hora de Inicio',
+      startDate: 'Fecha Incial',
+      startTime: 'Hora Inicial',
       endDate: 'Fecha Final',
       endTime: 'Hora Final',
       year: 'Año',
-      month1: 'Enero',
-      month2: 'Febrero',
-      month3: 'Marzo',
-      month4: 'Abril',
-      month5: 'Mayo',
-      month6: 'Junio',
-      month7: 'Julio',
-      month8: 'Agosto',
-      month9: 'Septiembre',
-      month10: 'Octubre',
-      month11: 'Noviembre',
-      month12: 'Diciembre',
+      month1: 'enero',
+      month2: 'febrero',
+      month3: 'marzo',
+      month4: 'abril',
+      month5: 'mayo',
+      month6: 'junio',
+      month7: 'julio',
+      month8: 'agosto',
+      month9: 'septiembre',
+      month10: 'octubre',
+      month11: 'noviembre',
+      month12: 'diciembre',
       // week: 'semana',
       weeks: {
-        sun: 'Dom',
-        mon: 'Lun',
-        tue: 'Mar',
-        wed: 'Mié',
-        thu: 'Jue',
-        fri: 'Vie',
-        sat: 'Sáb'
+        sun: 'dom',
+        mon: 'lun',
+        tue: 'mar',
+        wed: 'mié',
+        thu: 'jue',
+        fri: 'vie',
+        sat: 'sáb'
       },
       months: {
-        jan: 'Ene',
-        feb: 'Feb',
-        mar: 'Mar',
-        apr: 'Abr',
-        may: 'May',
-        jun: 'Jun',
-        jul: 'Jul',
-        aug: 'Ago',
-        sep: 'Sep',
-        oct: 'Oct',
-        nov: 'Nov',
-        dec: 'Dic'
+        jan: 'ene',
+        feb: 'feb',
+        mar: 'mar',
+        apr: 'abr',
+        may: 'may',
+        jun: 'jun',
+        jul: 'jul',
+        aug: 'ago',
+        sep: 'sep',
+        oct: 'oct',
+        nov: 'nov',
+        dec: 'dic'
       }
     },
     select: {
@@ -67,7 +67,7 @@ export default {
     },
     pagination: {
       goto: 'Ir a',
-      pagesize: '/pagina',
+      pagesize: '/página',
       total: 'Total {total}',
       pageClassifier: ''
     },
@@ -84,9 +84,9 @@ export default {
     table: {
       emptyText: 'Sin Datos',
       confirmFilter: 'Confirmar',
-      resetFilter: 'Limpiar',
-      clearFilter: 'Todo',
-      sumText: 'Sum' // to be translated
+      resetFilter: 'Reiniciar',
+      clearFilter: 'Despejar',
+      sumText: 'Suma'
     },
     tree: {
       emptyText: 'Sin Datos'
@@ -94,10 +94,10 @@ export default {
     transfer: {
       noMatch: 'No hay datos que coincidan',
       noData: 'Sin datos',
-      titles: ['List 1', 'List 2'], // to be translated
-      filterPlaceholder: 'Enter keyword', // to be translated
-      noCheckedFormat: '{total} items', // to be translated
-      hasCheckedFormat: '{checked}/{total} checked' // to be translated
+      titles: ['Lista 1', 'Lista 2'],
+      filterPlaceholder: 'Ingresar palabra clave',
+      noCheckedFormat: '{total} artículos',
+      hasCheckedFormat: '{checked}/{total} revisados'
     }
   }
 };

+ 104 - 0
src/locale/lang/he.js

@@ -0,0 +1,104 @@
+export default {
+  el: {
+    colorpicker: {
+      confirm: 'אישור',
+      clear: 'נקה'
+    },
+    datepicker: {
+      now: 'כעת',
+      today: 'היום',
+      cancel: 'בטל',
+      clear: 'נקה',
+      confirm: 'אישור',
+      selectDate: 'בחר תאריך',
+      selectTime: 'בחר זמן',
+      startDate: 'תאריך התחלה',
+      startTime: 'זמן התחלה',
+      endDate: 'תאריך סיום',
+      endTime: 'זמן סיום',
+      year: '',
+      month1: 'ינואר',
+      month2: 'פברואר',
+      month3: 'מרץ',
+      month4: 'אפריל',
+      month5: 'מאי',
+      month6: 'יוני',
+      month7: 'יולי',
+      month8: 'אוגוסט',
+      month9: 'ספטמבר',
+      month10: 'אוקטובר',
+      month11: 'נובמבר',
+      month12: 'דצמבר',
+      // week: 'week',
+      weeks: {
+        sun: 'א׳',
+        mon: 'ב׳',
+        tue: 'ג׳',
+        wed: 'ד׳',
+        thu: 'ה׳',
+        fri: 'ו׳',
+        sat: 'שבת'
+      },
+      months: {
+        jan: 'ינואר',
+        feb: 'פברואר',
+        mar: 'מרץ',
+        apr: 'אפריל',
+        may: 'מאי',
+        jun: 'יוני',
+        jul: 'יולי',
+        aug: 'אוגוסט',
+        sep: 'ספטמבר',
+        oct: 'אוקטובר',
+        nov: 'נובמבר',
+        dec: 'דצמבר'
+      }
+    },
+    select: {
+      loading: 'טוען',
+      noMatch: 'לא נמצאו נתונים',
+      noData: 'ללא נתונים',
+      placeholder: 'בחר'
+    },
+    cascader: {
+      noMatch: 'ללא נתונים מתאימים',
+      loading: 'טוען',
+      placeholder: 'בחר'
+    },
+    pagination: {
+      goto: 'עבור ל',
+      pagesize: '/page',
+      total: 'כולל {total}',
+      pageClassifier: ''
+    },
+    messagebox: {
+      title: 'הודעה',
+      confirm: 'אישור',
+      cancel: 'בטל',
+      error: 'קלט לא תקין'
+    },
+    upload: {
+      delete: 'מחק',
+      preview: 'תצוגה מקדימה',
+      continue: 'המשך'
+    },
+    table: {
+      emptyText: 'אין נתונים',
+      confirmFilter: 'אישור',
+      resetFilter: 'נקה',
+      clearFilter: 'הכל',
+      sumText: 'סך'
+    },
+    tree: {
+      emptyText: 'אין נתונים'
+    },
+    transfer: {
+      noMatch: 'אין נתונים מתאימים',
+      noData: 'ללא נתונים',
+      titles: ['רשימה 1', 'רשימה 2'], // to be translated
+      filterPlaceholder: 'הקלד', // to be translated
+      noCheckedFormat: 'פריטים {total}', // to be translated
+      hasCheckedFormat: ' אישור {checked}/{total}' // to be translated
+    }
+  }
+};

+ 5 - 5
src/locale/lang/ru-RU.js

@@ -87,7 +87,7 @@ export default {
       confirmFilter: 'Подтвердить',
       resetFilter: 'Сбросить',
       clearFilter: 'Все',
-      sumText: 'Sum' // to be translated
+      sumText: 'Сумма'
     },
     tree: {
       emptyText: 'Нет данных'
@@ -95,10 +95,10 @@ export default {
     transfer: {
       noMatch: 'Совпадений не найдено',
       noData: 'Нет данных',
-      titles: ['List 1', 'List 2'], // to be translated
-      filterPlaceholder: 'Enter keyword', // to be translated
-      noCheckedFormat: '{total} items', // to be translated
-      hasCheckedFormat: '{checked}/{total} checked' // to be translated
+      titles: ['Список 1', 'Список 2'],
+      filterPlaceholder: 'Введите ключевое слово',
+      noCheckedFormat: '{total} пунктов',
+      hasCheckedFormat: '{checked}/{total} выбрано'
     }
   }
 };

+ 8 - 8
src/locale/lang/ua.js

@@ -57,7 +57,7 @@ export default {
     select: {
       loading: 'Завантаження',
       noMatch: 'Співпадінь не знайдено',
-      noData: 'Нема даних',
+      noData: 'Немає даних',
       placeholder: 'Обрати'
     },
     cascader: {
@@ -83,22 +83,22 @@ export default {
       continue: 'Продовжити'
     },
     table: {
-      emptyText: 'Нема даних',
+      emptyText: 'Немає даних',
       confirmFilter: 'Підтвердити',
       resetFilter: 'Скинути',
       clearFilter: 'Все',
-      sumText: 'Sum' // to be translated
+      sumText: 'Сума'
     },
     tree: {
-      emptyText: 'Нема даних'
+      emptyText: 'Немає даних'
     },
     transfer: {
       noMatch: 'Співпадінь не знайдено',
       noData: 'Обрати',
-      titles: ['List 1', 'List 2'], // to be translated
-      filterPlaceholder: 'Enter keyword', // to be translated
-      noCheckedFormat: '{total} items', // to be translated
-      hasCheckedFormat: '{checked}/{total} checked' // to be translated
+      titles: ['Список 1', 'Список 2'],
+      filterPlaceholder: 'Введіть ключове слово',
+      noCheckedFormat: '{total} пунктів',
+      hasCheckedFormat: '{checked}/{total} вибрано'
     }
   }
 };

+ 3 - 1
src/utils/clickoutside.js

@@ -5,6 +5,7 @@ const nodeList = [];
 const ctx = '@@clickoutsideContext';
 
 let startClick;
+let seed = 0;
 
 !Vue.prototype.$isServer && on(document, 'mousedown', e => (startClick = e));
 
@@ -21,7 +22,8 @@ let startClick;
  */
 export default {
   bind(el, binding, vnode) {
-    const id = nodeList.push(el) - 1;
+    nodeList.push(el);
+    const id = seed++;
     const documentHandler = function(mouseup = {}, mousedown = {}) {
       if (!vnode.context ||
         !mouseup.target ||

+ 8 - 2
test/unit/specs/loading.spec.js

@@ -184,7 +184,7 @@ describe('Loading', () => {
       expect(loadingInstance.visible).to.false;
     });
 
-    it('target', () => {
+    it('target', done => {
       vm = createVue({
         template: `
         <div class="loading-container"></div>
@@ -192,8 +192,14 @@ describe('Loading', () => {
       }, true);
       loadingInstance = Loading({ target: '.loading-container' });
       let mask = document.querySelector('.el-loading-mask');
+      let container = document.querySelector('.loading-container');
       expect(mask).to.exist;
-      expect(mask.parentNode).to.equal(document.querySelector('.loading-container'));
+      expect(mask.parentNode).to.equal(container);
+      loadingInstance.close();
+      setTimeout(() => {
+        expect(container.style.position).to.equal('relative');
+        done();
+      }, 200);
     });
 
     it('body', () => {

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

@@ -219,6 +219,7 @@ describe('Pagination', () => {
       triggerEvent(input, 'change');
       setTimeout(() => {
         expect(vm.page).to.equal(10);
+        expect(input.value).to.equal('10');
 
         input.value = '我好帅';
         triggerEvent(input, 'change');

+ 34 - 0
test/unit/specs/rate.spec.js

@@ -95,6 +95,40 @@ describe('Rate', () => {
     expect(thirdIcon.style.color).to.equal('rgb(255, 153, 0)');
   });
 
+  it('colors are updated after prop is changed', done => {
+    vm = createVue({
+      template: `
+        <div>
+          <el-rate v-model="value" :colors="colors"></el-rate>
+        </div>
+      `,
+
+      computed: {
+        colors() {
+          if (this.muted) {
+            return ['#999', '#999', '#999'];
+          } else {
+            return ['#99A9BF', '#F7BA2A', '#FF9900'];
+          }
+        }
+      },
+      data() {
+        return {
+          value: 4,
+          muted: false
+        };
+      }
+    }, true);
+    setTimeout(() => {
+      vm.muted = true;
+      vm.$nextTick(() => {
+        const thirdIcon = vm.$el.querySelectorAll('.el-rate__item')[2].querySelector('.el-rate__icon');
+        expect(thirdIcon.style.color).to.equal('rgb(153, 153, 153)');
+        done();
+      });
+    }, 10);
+  });
+
   it('threshold', () => {
     vm = createVue({
       template: `

+ 13 - 11
test/unit/specs/select.spec.js

@@ -572,20 +572,22 @@ describe('Select', () => {
         }
       }
     }, true);
-    const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
     expect(vm.value.length).to.equal(2);
-    tagCloseIcons[1].click();
     setTimeout(() => {
-      expect(vm.value.length).to.equal(1);
-      expect(window.console.log.callCount).to.equal(1);
-      tagCloseIcons[0].click();
+      const tagCloseIcons = vm.$el.querySelectorAll('.el-tag__close');
+      tagCloseIcons[1].click();
       setTimeout(() => {
-        expect(vm.value.length).to.equal(0);
-        expect(window.console.log.callCount).to.equal(2);
-        window.console.log.restore();
-        done();
-      }, 100);
-    }, 100);
+        expect(vm.value.length).to.equal(1);
+        expect(window.console.log.callCount).to.equal(1);
+        tagCloseIcons[0].click();
+        setTimeout(() => {
+          expect(vm.value.length).to.equal(0);
+          expect(window.console.log.callCount).to.equal(2);
+          window.console.log.restore();
+          done();
+        }, 50);
+      }, 50);
+    }, 50);
   });
 
   it('multiple limit', done => {