Sfoglia il codice sorgente

Merge branch 'dev' into es-doc

# Conflicts:
#	FAQ.md
Leopoldthecoder 7 anni fa
parent
commit
27b271031e
94 ha cambiato i file con 1489 aggiunte e 625 eliminazioni
  1. 76 0
      .github/CONTRIBUTING.es.md
  2. 1 1
      .github/PULL_REQUEST_TEMPLATE.md
  3. 28 0
      CHANGELOG.en-US.md
  4. 28 0
      CHANGELOG.zh-CN.md
  5. 163 89
      FAQ.md
  6. 0 4
      README.md
  7. 0 2
      build/bin/build-entry.js
  8. 1 1
      build/bin/version.js
  9. 1 0
      examples/docs/en-US/cascader.md
  10. 1 1
      examples/docs/en-US/collapse.md
  11. 8 2
      examples/docs/en-US/date-picker.md
  12. 2 2
      examples/docs/en-US/datetime-picker.md
  13. 1 0
      examples/docs/en-US/i18n.md
  14. 31 4
      examples/docs/en-US/input.md
  15. 3 1
      examples/docs/en-US/loading.md
  16. 2 1
      examples/docs/en-US/message-box.md
  17. 13 0
      examples/docs/en-US/pagination.md
  18. 1 0
      examples/docs/en-US/quickstart.md
  19. 2 1
      examples/docs/en-US/select.md
  20. 2 1
      examples/docs/en-US/table.md
  21. 3 3
      examples/docs/en-US/time-picker.md
  22. 1 0
      examples/docs/zh-CN/cascader.md
  23. 1 1
      examples/docs/zh-CN/collapse.md
  24. 6 14
      examples/docs/zh-CN/date-picker.md
  25. 2 2
      examples/docs/zh-CN/datetime-picker.md
  26. 1 0
      examples/docs/zh-CN/i18n.md
  27. 31 4
      examples/docs/zh-CN/input.md
  28. 3 1
      examples/docs/zh-CN/loading.md
  29. 1 0
      examples/docs/zh-CN/message-box.md
  30. 13 0
      examples/docs/zh-CN/pagination.md
  31. 1 0
      examples/docs/zh-CN/quickstart.md
  32. 2 1
      examples/docs/zh-CN/select.md
  33. 2 1
      examples/docs/zh-CN/table.md
  34. 2 2
      examples/docs/zh-CN/time-picker.md
  35. 0 1
      examples/index.tpl
  36. 1 1
      examples/versions.json
  37. 1 1
      package.json
  38. 2 0
      packages/autocomplete/src/autocomplete.vue
  39. 3 1
      packages/breadcrumb/src/breadcrumb.vue
  40. 5 1
      packages/cascader/src/main.vue
  41. 19 5
      packages/cascader/src/menu.vue
  42. 1 1
      packages/date-picker/README.md
  43. 15 6
      packages/date-picker/src/basic/time-spinner.vue
  44. 5 1
      packages/date-picker/src/panel/date-range.vue
  45. 1 1
      packages/date-picker/src/panel/date.vue
  46. 7 0
      packages/date-picker/src/panel/time-range.vue
  47. 6 0
      packages/date-picker/src/panel/time.vue
  48. 0 1
      packages/dialog/src/component.vue
  49. 1 1
      packages/dropdown/src/dropdown-menu.vue
  50. 6 2
      packages/dropdown/src/dropdown.vue
  51. 5 0
      packages/form/src/form-item.vue
  52. 40 12
      packages/input/src/input.vue
  53. 4 2
      packages/menu/src/menu.vue
  54. 1 0
      packages/message-box/src/main.js
  55. 10 6
      packages/message-box/src/main.vue
  56. 25 20
      packages/pagination/src/pagination.js
  57. 3 3
      packages/popover/src/main.vue
  58. 1 1
      packages/select/src/option.vue
  59. 8 4
      packages/select/src/select.vue
  60. 6 4
      packages/table/src/table-body.js
  61. 2 2
      packages/table/src/table-column.js
  62. 6 11
      packages/table/src/table.vue
  63. 1 1
      packages/tag/src/tag.vue
  64. 1 1
      packages/theme-chalk/package.json
  65. 7 1
      packages/theme-chalk/src/button.scss
  66. 3 2
      packages/theme-chalk/src/common/var.scss
  67. BIN
      packages/theme-chalk/src/fonts/element-icons.ttf
  68. BIN
      packages/theme-chalk/src/fonts/element-icons.woff
  69. 2 2
      packages/theme-chalk/src/icon.scss
  70. 12 0
      packages/theme-chalk/src/input.scss
  71. 1 0
      packages/theme-chalk/src/menu.scss
  72. 43 2
      packages/theme-chalk/src/pagination.scss
  73. 1 1
      packages/theme-chalk/src/select.scss
  74. 8 6
      packages/theme-chalk/src/table.scss
  75. 3 3
      packages/theme-chalk/src/tag.scss
  76. 3 2
      packages/tooltip/src/main.js
  77. 3 3
      packages/tree/src/tree.vue
  78. 1 3
      src/index.js
  79. 11 11
      src/locale/lang/en.js
  80. 10 10
      src/locale/lang/fa.js
  81. 5 5
      src/locale/lang/ko.js
  82. 109 0
      src/locale/lang/kz.js
  83. 109 0
      src/locale/lang/lt.js
  84. 109 0
      src/locale/lang/mn.js
  85. 12 12
      src/locale/lang/nl.js
  86. 27 21
      src/utils/clickoutside.js
  87. 2 1
      src/utils/popper.js
  88. 2 3
      test/unit/specs/dropdown.spec.js
  89. 18 3
      test/unit/specs/message-box.spec.js
  90. 15 11
      test/unit/specs/pagination.spec.js
  91. 24 0
      test/unit/specs/time-picker.spec.js
  92. 286 0
      types/element-ui.d.ts
  93. 2 284
      types/index.d.ts
  94. 42 10
      yarn.lock

+ 76 - 0
.github/CONTRIBUTING.es.md

@@ -0,0 +1,76 @@
+# Guía para Contribuidores a `Element UI`
+
+¡Hola! Gracias por elegir [Element UI](http://element.eleme.io/#/en-US).
+
+`Element UI` es un archivo de componentes para desarrolladores y para gerentes de productos ‘web’ basado en [Vue 2.0](https://vuejs.org/)
+
+Estamos orgullosos de que usted esta interesado en contribuir al proyecto `Element`. Antes de someter sus contribuciones, por favor tome un momentito para leer estas simples guías para contribuidores.
+
+
+## Guía Para Reportar Problemas (“Issues”)
+
+- [“Issues”]( https://elementui.github.io/issue-generator) son exclusivamente para informar de errores, sugerencias o solicitaciones para funcionalidad adicional referente a diseño. Preguntas de otro tipo corren el riesgo de ser cerradas inmediatamente. Sí tiene preguntas sobre el uso de `Element`, vea [Gitter](https://gitter.im/element-en/Lobby) para más ayuda.
+
+- Antes de someter un informe sobre algún problema, sírvase de revisar  sí ya hubo un informe.
+
+- Por favor especifique que versión de `Element` y `Vue` que esta utilizando, y que versión de sistema operativo y que versión de navegador web que está utilizando. [JSFiddle](https://jsfiddle.net/) esta recomendado para crear un entorno para reproducir el problema claramente.
+
+
+## Guías para un “Pull Request (PR)”
+
+- Crea una bifurcación (“fork”) del repositorio a su propia cuenta en github.com. Por favor no crea ramas nuevas aquí.
+
+- Cuando cometa su cambio, formatea en esta forma: `[Nombre de componente]: Datos sobre el “commit”.` (por ejemplo. `Button: Reparación de xxx error`)
+
+- **DE NINGUNA MANERA** incluya archivos dentro del directorio `lib`.
+
+- Asegúrese de que el comando `npm run dist` produzca los archivos correctos.
+
+- Para asegurar compatibilidad y reducir tamaño de los archivos, nuestra configuración de `babel` solo importa `preset-2015`, así que IPAs como  Array.prototype.find` y `Object.assign` en `ES2015` no son recomendados. Puede importar “polyfills” terceros, sí es necesario.
+
+- “Rebase” antes de crear un “pull request (PR)” para mantener la historia de “commits” limpia.
+
+- Asegúrese que sus PRs se refrieran a la rama `dev`  y no a la rama  `master`.
+
+- Si su PR arregla un error técnico, por favor, haga referencia al error especifico.
+
+- Fusión de un PR requiere dos mantenedores: el primero aprueba los cambios después de revisar, y entonces el segundo mantenedor revisa los cambios y hace la fusión.
+
+
+## Requerimientos Técnicos 
+`Node.js 4+` y `NPM 3+` son requisitos
+.
+```shell
+git clone git@github.com:ElemeFE/element.git
+npm run dev
+
+# abra http://localhost:8085
+```
+
+Para usuarios chinos, [yarn](https://github.com/yarnpkg/yarn) con `taobao registry` es recomendado, sí la instalación de dependencias es lenta.
+
+```shell
+npm i yarn -g
+yarn config set registry https://registry.npm.taobao.org
+yarn
+npm run dev
+
+# abra http://localhost:8085
+```
+
+Para armar:
+
+```
+shell
+npm run dist
+```
+
+## Guía Para Desarrollo de Componentes
+- Corra el comando `make new <component-name>` para crear el directorio de su proyecto para un componente nuevo. Verifique su código fuente test, configuración para armar, documentación y `package.json` están incluidos.
+- Refiérase al `Button` para componentes anidados.
+- Refiérase al `Select` para componentes que dependen de otros componentes.
+
+
+## Estilo de Desarrollo
+Por favor acate a este estilo [ESLint](https://github.com/ElemeFE/eslint-config-elemefe) configuración de [ElemeFE](https://github.com/elemefe).
+

+ 1 - 1
.github/PULL_REQUEST_TEMPLATE.md

@@ -1,5 +1,5 @@
 Please make sure these boxes are checked before submitting your PR, thank you!
 
-* [ ] Make sure you follow Element's contributing guide ([中文](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.zh-CN.md) | [English](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.en-US.md)).
+* [ ] Make sure you follow Element's contributing guide ([中文](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.zh-CN.md) | [English](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.en-US.md) | [Español](https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.es.md)).
 * [ ] Make sure you are merging your commits to `dev` branch.
 * [ ] Add some descriptions and refer relative issues for you PR.

+ 28 - 0
CHANGELOG.en-US.md

@@ -1,5 +1,33 @@
 ## Changelog
 
+### 2.0.7
+
+*2017-11-29*
+
+- Fixed disabled text button style, #8570
+
+### 2.0.6
+
+*2017-11-29*
+
+- Fixed style bug of Table's sorting icons, #8405
+- Fixed trigger mechanism for Popover when its `trigger` is manual, #8467
+- Added `prefix-icon` and `suffix-icon` attributes for Autocomplete, #8446 (by @liyanlong)
+- Added `separator` attribute for Cascader, #8501
+- Added `clearable` attribute for Input, #8509 (by @lbogdan)
+- Added `background` attribute for Pagination, #8553
+
+### 2.0.5
+
+*2017-11-17*
+
+- Fixed Popover, Tree, Breadcrumb and Cascader regression in 2.0.4, #8188 #8217 #8283
+- Fixed memory leak of clickoutside directive, #8168 #8225 (by @badpunman @STLighter)
+- Fixed multiple Select height when its value is cleared, #8317 (by @luciy)
+- Added `collapse-tags` attribute for multiple Select to replace tags with one line of text, #8190
+- Fixed high CPU consumption caused by hidden Table, #8351
+- Now you can use `doLayout` method of Table to update its layout, #8351
+
 ### 2.0.4
 
 *2017-11-10*

+ 28 - 0
CHANGELOG.zh-CN.md

@@ -1,5 +1,33 @@
 ## 更新日志
 
+### 2.0.7
+
+*2017-11-29*
+
+- 修复禁用文字按钮的样式问题,#8570
+
+### 2.0.6
+
+*2017-11-29*
+
+- 修复 Table 排序图标的样式问题,#8405
+- 修复 `trigger` 为 manual 的 Popover 的触发问题,#8467
+- 新增 Autocomplete 的 `prefix-icon` 和 `suffix-icon` 属性,#8446(by @liyanlong)
+- 新增 Cascader 的 `separator` 属性,#8501
+- 新增 Input 的 `clearable` 属性,#8509(by @lbogdan)
+- 新增 Pagination 的 `background` 属性,#8553
+
+### 2.0.5
+
+*2017-11-17*
+
+- 修复上个版本引入的 Popover、Tree、Breadcrumb、Cascader 的 bug,#8188 #8217 #8283
+- 修复 clickoutside 指令的内存泄露问题,#8168 #8225(by @badpunman @STLighter)
+- 修复默认尺寸的多选 Select 在清空选项后输入框高度不随之更新的问题,#8317(by @luciy)
+- 新增 Select 的 `collapse-tags` 属性,用于在多选时以文字代替 Tag,避免组件高度的增大,#8190
+- 修复被隐藏的 Table 会造成 CPU 占用持续增加的问题,#8351
+- 开放 Table 的 `doLayout` 方法,用于重新计算 Table 的布局,#8351
+
 ### 2.0.4
 
 *2017-11-10*

+ 163 - 89
FAQ.md

@@ -1,143 +1,217 @@
 ## 常见问题
 
 <details>
-<summary>给组件绑定的事件为什么无法触发?</summary>
-
-在 Vue 2.0 中,为**自定义**组件绑定**原生**事件必须使用 `.native` 修饰符:
-```html
-<my-component @click.native="handleClick">Click Me</my-component>
-```
-
-从易用性的角度出发,我们对 `Button` 组件进行了处理,使它可以监听 `click` 事件:
-```html
-<el-button @click="handleButtonClick">Click Me</el-button>
-```
-
-但是对于其他组件,还是需要添加 `.native` 修饰符。
+  <summary>给组件绑定的事件为什么无法触发?</summary>
+  
+  在 Vue 2.0 中,为**自定义**组件绑定**原生**事件必须使用 `.native` 修饰符:
+  ```html
+  <my-component @click.native="handleClick">Click Me</my-component>
+  ```
+  
+  从易用性的角度出发,我们对 `Button` 组件进行了处理,使它可以监听 `click` 事件:
+  ```html
+  <el-button @click="handleButtonClick">Click Me</el-button>
+  ```
+  
+  但是对于其他组件,还是需要添加 `.native` 修饰符。
 </details>
 
 <details>
-<summary>如何在 Table 组件的每一行添加操作该行数据的按钮?</summary>
-
-使用 [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) 即可:
-```html
-<el-table-column label="操作">
-  <template slot-scope="props">
-    <el-button @click.native="showDetail(props.row)">查看详情</el-button>
-  </template>
-</el-table-column>
-```
-参数 `row` 即为对应行的数据。
+  <summary>如何在 Table 组件的每一行添加操作该行数据的按钮?</summary>
+  
+  使用 [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots) 即可:
+  ```html
+  <el-table-column label="操作">
+    <template slot-scope="props">
+      <el-button @click.native="showDetail(props.row)">查看详情</el-button>
+    </template>
+  </el-table-column>
+  ```
+  参数 `row` 即为对应行的数据。
 </details>
 
 <details>
-<summary>Tree 组件的 `render-content` 和 Table 组件的 `render-header` 怎么用?</summary>
-
-请阅读 Vue 文档 [Render Function](http://vuejs.org/v2/guide/render-function.html) 的相关内容。注意,使用 JSX 来写 Render Function 的话,需要安装 `babel-plugin-transform-vue-jsx`,并参照其[文档](https://github.com/vuejs/babel-plugin-transform-vue-jsx)进行配置。
+  <summary>Tree 组件的 `render-content` 和 Table 组件的 `render-header` 怎么用?</summary>
+  
+  请阅读 Vue 文档 [Render Function](http://vuejs.org/v2/guide/render-function.html) 的相关内容。注意,使用 JSX 来写 Render Function 的话,需要安装 `babel-plugin-transform-vue-jsx`,并参照其[文档](https://github.com/vuejs/babel-plugin-transform-vue-jsx)进行配置。
 </details>
 
 <details>
-<summary>所有组件的任意属性都支持 `.sync` 修饰符吗?</summary>
+  <summary>所有组件的任意属性都支持 `.sync` 修饰符吗?</summary>
   
-不是。对于支持 `.sync` 修饰符的属性,我们会在文档的 API 表格中注明。更多 `.sync` 的用法请查看 [Vue 文档](https://vuejs.org/v2/guide/components.html#sync-Modifier)。
+  不是。对于支持 `.sync` 修饰符的属性,我们会在文档的 API 表格中注明。更多 `.sync` 的用法请查看 [Vue 文档](https://vuejs.org/v2/guide/components.html#sync-Modifier)。
 </details>
 
 <details>
-<summary>你们的文档怎么偷偷更新了?</summary>
-
-我们只会在 Element 发布新版本时同步更新文档,以体现最新的变化。详细的更新内容可以查看 [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.zh-CN.md)。
+  <summary>你们的文档怎么偷偷更新了?</summary>
+  
+  我们只会在 Element 发布新版本时同步更新文档,以体现最新的变化。详细的更新内容可以查看 [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.zh-CN.md)。
 </details>
 
 <details>
-<summary>在项目中引入 Element,但是 CSS 报错/字体文件报错/组件没有样式是什么原因?</summary>
-
-请参考我们提供的 [starter kit](https://github.com/ElementUI/element-starter),在 webpack 的 loaders 中正确配置 file-loader、css-loader 和 style-loader。此外,我们还提供了基于 [cooking](https://github.com/ElementUI/element-cooking-starter) 和 [laravel](https://github.com/ElementUI/element-in-laravel-starter) 的项目模板。
+  <summary>在项目中引入 Element,但是 CSS 报错/字体文件报错/组件没有样式是什么原因?</summary>
+  
+  请参考我们提供的 [starter kit](https://github.com/ElementUI/element-starter),在 webpack 的 loaders 中正确配置 file-loader、css-loader 和 style-loader。此外,我们还提供了基于 [cooking](https://github.com/ElementUI/element-cooking-starter) 和 [laravel](https://github.com/ElementUI/element-in-laravel-starter) 的项目模板。
 </details>
 
 <details>
-<summary>将 Element 克隆至本地,运行时为何会报错/跑不起来?</summary>
-
-首先,确保克隆的是 master 分支的最新代码,并且文件完整。其次,确保本地的 node 版本在 4.0 以上,npm 版本在 3.0 以上。最后,可以启动开发环境:
-
-```bash
-npm run dev
-```
-
-或是直接打包:
-
-```bash
-npm run dist
-```
+  <summary>将 Element 克隆至本地,运行时为何会报错/跑不起来?</summary>
+  
+  首先,确保克隆的是 master 分支的最新代码,并且文件完整。其次,确保本地的 node 版本在 4.0 以上,npm 版本在 3.0 以上。最后,可以启动开发环境:
+  
+  ```bash
+  npm run dev
+  ```
+  
+  或是直接打包:
+  
+  ```bash
+  npm run dist
+  ```
 </details>
 
 ## FAQ
 
 <details>
-<summary>Why are my event listeners not working?</summary>
-
-In Vue 2.0, adding **native** event handlers in **custom** components requires a `.native` modifier:
-```html
-<my-component @click.native="handleClick">Click Me</my-component>
-```
-
-For the sake of usability, we processed `Button` so it can listen to `click` events:
-```html
-<el-button @click="handleButtonClick">Click Me</el-button>
-```
-
-For other components, the `.native` modifier is still mandatory.
+  <summary>Why are my event listeners not working?</summary>
+  
+  In Vue 2.0, adding **native** event handlers in **custom** components requires a `.native` modifier:
+  ```html
+  <my-component @click.native="handleClick">Click Me</my-component>
+  ```
+  
+  For the sake of usability, we processed `Button` so it can listen to `click` events:
+  ```html
+  <el-button @click="handleButtonClick">Click Me</el-button>
+  ```
+  
+  For other components, the `.native` modifier is still mandatory.
 </details>
 
 <details>
-<summary>How do I add buttons in each row of Table to operate data of that row?</summary>
-
-Just use [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots):
-```html
-<el-table-column label="Operations">
-  <template slot-scope="props">
-    <el-button @click.native="showDetail(props.row)">Details</el-button>
-  </template>
-</el-table-column>
-```
-The parameter `row` is the data object of corresponding row.
+  <summary>How do I add buttons in each row of Table to operate data of that row?</summary>
+  
+  Just use [Scoped slot](https://vuejs.org/v2/guide/components.html#Scoped-Slots):
+  ```html
+  <el-table-column label="Operations">
+    <template slot-scope="props">
+      <el-button @click.native="showDetail(props.row)">Details</el-button>
+    </template>
+  </el-table-column>
+  ```
+  The parameter `row` is the data object of corresponding row.
 </details>
 
 <details>
-<summary>How do `render-content` of Tree and `render-header` of Table work?</summary>
+  <summary>How do `render-content` of Tree and `render-header` of Table work?</summary>
+  
+  Please refer to [Render Function](http://vuejs.org/v2/guide/render-function.html) in Vue's documentation. In addition, if you are writing render functions with JSX, `babel-plugin-transform-vue-jsx` is required. See [here](https://github.com/vuejs/babel-plugin-transform-vue-jsx) for its configurations.
+</details>
 
-Please refer to [Render Function](http://vuejs.org/v2/guide/render-function.html) in Vue's documentation. In addition, if you are writing render functions with JSX, `babel-plugin-transform-vue-jsx` is required. See [here](https://github.com/vuejs/babel-plugin-transform-vue-jsx) for its configurations.
+<details>
+  <summary>Can I use `.sync` modifier on every attribute?</summary>
+  
+  No, only a few attributes supports the `.sync` modifier, and we have explicitly marked them on the documentation's API table. For more information about `.sync`, please refer to [Vue documentation](https://vuejs.org/v2/guide/components.html#sync-Modifier).
 </details>
 
 <details>
-<summary>Can I use `.sync` modifier on every attribute?</summary>
+  <summary>When do you update documentations of Element?</summary>
   
-No, only a few attributes supports the `.sync` modifier, and we have explicitly marked them on the documentation's API table. For more information about `.sync`, please refer to [Vue documentation](https://vuejs.org/v2/guide/components.html#sync-Modifier).
+  We update documentations only when a new version of Element is published so that it reflects all the changes introduced in that version. Updated changed can be found in the [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.en-US.md)。
 </details>
 
 <details>
-<summary>When do you update documentations of Element?</summary>
+  <summary>I imported Element in my project, but why does it report CSS error/font file error/components have no style?</summary>
+  
+  Please refer to our [starter kit](https://github.com/ElementUI/element-starter) and correctly configure file-loader, css-loader and style-loader in webpack config file. Besides, we also provide templated based on [cooking](https://github.com/ElementUI/element-cooking-starter) and [laravel](https://github.com/ElementUI/element-in-laravel-starter).
+</details>
 
-We update documentations only when a new version of Element is published so that it reflects all the changes introduced in that version. Updated changed can be found in the [changelog](https://github.com/ElemeFE/element/blob/master/CHANGELOG.en-US.md)。
+<details>
+  <summary>I cloned Element's repo, but failed to run it. How do I solve it?</summary>
+  
+  First, please make sure to clone the latest code in master branch and cloned files are intact. Then, note that the version of Nodejs should be 4.0+ and npm 3.0+. Finally, activate development:
+  
+  ```bash
+  npm run dev
+  ```
+  
+  or build it:
+  
+  ```bash
+  npm run dist
+  ```
 </details>
 
+## Preguntas más frecuentes
+
 <details>
-<summary>I imported Element in my project, but why does it report CSS error/font file error/components have no style?</summary>
+  <summary>¿Porque mis receptores de eventos no funcionan?</summary>
+  
+  En Vue 2.0, agregando **nativos** receptores de evento **a medida** componentes requiere el modificador `.native`:
+  ```
+  html
+  <mi-componente @click.native="handleClick">Haga Clic Aquí</mi-componente>
+  ```
+  
+  Para conveniencia, hemos ya procesado eventos para el componente `Button` para que el interfaz sea consistente con `clic` eventos de otros componentes:
+  
+  ```html
+  <el-button @click="handleButtonClick">Haga Clic Aquí</el-button>
+  ```
+  
+  Para otros componentes el uso del modificador `.native` sigue siendo obligatorio.
+</details>
 
-Please refer to our [starter kit](https://github.com/ElementUI/element-starter) and correctly configure file-loader, css-loader and style-loader in webpack config file. Besides, we also provide templated based on [cooking](https://github.com/ElementUI/element-cooking-starter) and [laravel](https://github.com/ElementUI/element-in-laravel-starter).
+<details>
+  <summary>¿Como agrego botones en cada linea de una tabla para que operen en los datos de esa linea?</summary>
+  
+  Simplemente agregue [“Scoped slot”](https://vuejs.org/v2/guide/components.html#Scoped-Slots):
+  ```html
+  <el-table-column label="Operaciones">
+    <template slot-scope="props">
+      <el-button @click.native="verDetalles(props.row)">Detalles</el-button>
+    </template>
+  </el-table-column>
+  ```
+  El parámetro `row` contiene los datos de la linea correspondiente de la tabla.
 </details>
 
 <details>
-<summary>I cloned Element's repo, but failed to run it. How do I solve it?</summary>
+  <summary>¿Como funcionan `render-content` de `Tree` y `render-header` de `Table`?</summary>
+  
+  Por favor refiérase a [Función de representación](http://vuejs.org/v2/guide/render-function.html) en la documentación de `Vue`. Adicionalmente, sí usted está escribiendo funciones de representar con JSX, se requiere el componente `babel-plugin-transform-vue-jsx`. Más información [aquí](https://github.com/vuejs/babel-plugin-transform-vue-jsx) para su uso y configuración.
+</details>
 
-First, please make sure to clone the latest code in master branch and cloned files are intact. Then, note that the version of Nodejs should be 4.0+ and npm 3.0+. Finally, activate development:
+<details>
+  <summary>¿Puedo usar el modificador `.sync` con cada atributo?</summary>
+  
+  No, solamente un grupo pequeño de atributos apoyan el modificador `.sync`, y están anotados claramente en la documentación del IPA. Para información adicional sobre `.sync`, por favor refiérase a [documentación de Vue](https://vuejs.org/v2/guide/components.html#sync-Modifier).
+</details>
 
-```bash
-npm run dev
-```
+<details>
+  <summary>¿Cuando añaden a la documentación de `Element`?</summary>
+  
+  Añadamos la documentación con cada versión nueva de `Element` y los cambios reflejan los cambios del software de esa versión. Los cambios actuales y históricos se encuentran [aquí](https://github.com/ElemeFE/element/blob/master/CHANGELOG.en-US.md).
+</details>
 
-or build it:
+<details>
+  <summary>¿Importé `Element` a mi proyecto pero tengo errores con `CSS` y/o fuentes y mis componentes no tienen ningún estilo?</summary>
+  
+  Refiérase a [nuestro ‘kit’ de inicio](https://github.com/ElementUI/element-starter) y configure correctamente `file-loader`, `css-loader` y `style-loader` en el archivo `webpack config`. Además, proveemos un ejemplar para [cooking](https://github.com/ElementUI/element-cooking-starter) y para [laravel](https://github.com/ElementUI/element-in-laravel-starter).
+</details>
 
-```bash
-npm run dist
-```
+<details>
+  <summary>Hice un clon del repositorio de `Element` pero no arranca. ¿Como lo resuelvo?</summary>
+  
+  Primero, pro favor, asegúrese de usar la versión más corriente en la rama  `master` y que los archivos están en orden. Después, revise sí la versión de `Nodejs` es 4.0+ y `npm` debe ser 3.0+. Finalmente active el modo desarrollo:
+  
+  ```bash
+  npm run dev
+  ```
+  
+  O arme su aplicación así:
+  
+  ```bash
+  npm run dist
+  ```
 </details>

+ 0 - 4
README.md

@@ -18,10 +18,6 @@
 
 > A Vue.js 2.0 UI Toolkit for Web.
 
-<!--<a target='_blank' rel='nofollow' href='https://app.codesponsor.io/link/bD3dKbdDE2F7Ky9LUN1kjTFK/ElemeFE/element'>-->
-  <!--<img alt='Sponsor' width='888' height='68' src='https://app.codesponsor.io/embed/bD3dKbdDE2F7Ky9LUN1kjTFK/ElemeFE/element.svg' />-->
-<!--</a >-->
-
 ## Links
 - Homepage and documentation
   - International users: http://element.eleme.io/

+ 0 - 2
build/bin/build-entry.js

@@ -20,8 +20,6 @@ const components = [
 ];
 
 const install = function(Vue, opts = {}) {
-  /* istanbul ignore if */
-  if (install.installed) return;
   locale.use(opts.locale);
   locale.i18n(opts.i18n);
 

+ 1 - 1
build/bin/version.js

@@ -1,6 +1,6 @@
 var fs = require('fs');
 var path = require('path');
 var version = process.env.VERSION || require('../../package.json').version;
-var content = { '1.0.9': '1.0', '1.1.6': '1.1', '1.2.9': '1.2', '1.3.7': '1.3', '1.4.9': '1.4' };
+var content = { '1.4.12': '1.4' };
 if (!content[version]) content[version] = '2.0';
 fs.writeFileSync(path.resolve(__dirname, '../../examples/versions.json'), JSON.stringify(content));

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

@@ -1669,6 +1669,7 @@ Search and select options with a keyword.
 | options   | data of the options | array | — | — |
 | props | configuration options, see the following table | object | — | — |
 | value | selected value | array | — | — |
+| separator | option separator | string | — | / |
 | popper-class | custom class name for Cascader's dropdown | string | — | — |
 | placeholder | input placeholder | string | — | Select |
 | disabled  | whether Cascader is disabled | boolean |  — | false |

+ 1 - 1
examples/docs/en-US/collapse.md

@@ -111,7 +111,7 @@ Besides using the `title` attribute, you can customize panel title with named sl
 <el-collapse accordion>
   <el-collapse-item name="1">
     <template slot="title">
-      Consistency<i class="header-icon el-icon-information"></i>
+      Consistency<i class="header-icon el-icon-info"></i>
     </template>
     <div>Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;</div>
     <div>Consistent within interface: all elements should be consistent, such as: design style, icons and texts, position of elements, etc.</div>

+ 8 - 2
examples/docs/en-US/date-picker.md

@@ -3,6 +3,9 @@
     data() {
       return {
         pickerOptions1: {
+          disabledDate(time) {
+            return time.getTime() > Date.now();
+          },
           shortcuts: [{
             text: 'Today',
             onClick(picker) {
@@ -127,6 +130,9 @@ Basic date picker measured by 'day'.
     data() {
       return {
         pickerOptions1: {
+          disabledDate(time) {
+            return time.getTime() > Date.now();
+          },
           shortcuts: [{
             text: 'Today',
             onClick(picker) {
@@ -382,13 +388,13 @@ This feature is at alpha stage. Feedback welcome.
 | start-placeholder | placeholder for the start date in range mode | string | — | — |
 | end-placeholder | placeholder for the end date in range mode | string | — | — |
 | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
-| format | format of the displayed value in the input box | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd |
+| format | format of the displayed value in the input box | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss`, AM/PM `A` | yyyy-MM-dd |
 | align | alignment | left/center/right | left |
 | popper-class | custom class name for DatePicker's dropdown | string | — | — |
 | picker-options | additional options, check the table below | object | — | {} |
 | range-separator | range separator | string | — | '-' |
 | default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — |
-| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | — |
+| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss`, AM/PM `A` | — |
 | name | same as `name` in native input | string | — | — |
 | unlink-panels | unlink two date-panels in range-picker | boolean | — | false |
 

+ 2 - 2
examples/docs/en-US/datetime-picker.md

@@ -247,13 +247,13 @@ DateTimePicker is derived from DatePicker and TimePicker. For a more detailed ex
 | end-placeholder | placeholder for the end date in range mode | string | — | — |
 | time-arrow-control | whether to pick time using arrow buttons | boolean | — | false |
 | type | type of the picker | string | year/month/date/datetime/ week/datetimerange/daterange | date |
-| format | format of the displayed value in the input box | string | year `yyyy` month `MM` day `dd`, hour `HH`, minute `mm`, second `ss` | yyyy-MM-dd |
+| format | format of the displayed value in the input box | string | year `yyyy` month `MM` day `dd`, hour `HH`, minute `mm`, second `ss`, AM/PM `A` | yyyy-MM-dd |
 | align | alignment | left/center/right | left |
 | popper-class | custom class name for DateTimePicker's dropdown | string | — | — |
 | picker-options | additional options, check the table below | object | — | {} |
 | range-separator | range separator | string | - | '-' |
 | default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — |
-| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss` | — |
+| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss`, AM/PM `A` | — |
 | name | same as `name` in native input | string | — | — |
 | unlink-panels | unllink two date-panels in range-picker | boolean | — | false |
 

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

@@ -207,6 +207,7 @@ Currently Element ships with the following languages:
   <li>Slovenian (sl)</li>
   <li>Arabic (ar)</li>
   <li>Hebrew (he)</li>
+  <li>Lithuanian (lt)</li>
 </ul>
 
 If your target language is not included, you are more than welcome to contribute: just add another language config [here](https://github.com/ElemeFE/element/tree/master/src/locale/lang) and create a pull request.

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

@@ -16,6 +16,7 @@
         input7: '',
         input8: '',
         input9: '',
+        input10: '',
         textarea: '',
         textarea2: '',
         textarea3: '',
@@ -188,6 +189,29 @@ export default {
 ```
 :::
 
+### Clearable
+
+::: demo Make the Input clearable with the `clearable` attribute.
+
+```html
+<el-input
+  placeholder="Please input"
+  v-model="input10"
+  clearable>
+</el-input>
+
+<script>
+export default {
+  data() {
+    return {
+      input10: ''
+    }
+  }
+}
+</script>
+```
+:::
+
 ### Input with icon
 
 Add an icon to indicate input type.
@@ -623,6 +647,7 @@ Search data from server-side.
 |maxlength| maximum Input text length| number| — | — |
 |minlength| minimum Input text length| number | — | — |
 |placeholder| placeholder of Input| string | — | — |
+| clearable | whether to show clear button | boolean | — | false |
 |disabled | whether Input is disabled | boolean | — | false |
 |size | size of Input, works when `type` is not 'textarea' | string | medium / small / mini | — |
 | prefix-icon   | prefix icon class  | string          | — | — |
@@ -644,10 +669,10 @@ Search data from server-side.
 
 | Name | Description |
 |------|--------|
-| prefix | content as Input prefix |
-| suffix | content as Input suffix |
-| prepend | content to prepend before Input |
-| append | content to append after Input |
+| prefix | content as Input prefix, only works when `type` is 'text' |
+| suffix | content as Input suffix, only works when `type` is 'text' |
+| prepend | content to prepend before Input, only works when `type` is 'text' |
+| append | content to append after Input, only works when `type` is 'text' |
 
 ### Input Events
 
@@ -674,6 +699,8 @@ Attribute | Description | Type | Options | Default
 | name | same as `name` in native input | string | — | — |
 | select-when-unmatched | whether to emit a `select` event on enter when there is no autocomplete match | boolean | — | false |
 | label | label text | string | — | — |
+| prefix-icon | prefix icon class | string | — | — |
+| suffix-icon | suffix icon class | string | — | — |
 
 ### Autocomplete slots
 

+ 3 - 1
examples/docs/en-US/loading.md

@@ -233,7 +233,9 @@ Loading.service(options);
 The parameter `options` is the configuration of Loading, and its details can be found in the following table. `LoadingService` returns a Loading instance, and you can close it by invoking its `close` method:
 ```javascript
 let loadingInstance = Loading.service(options);
-loadingInstance.close();
+this.$nextTick(() => { // Loading should be closed asynchronously
+  loadingInstance.close();
+});
 ```
 Note that in this case the full screen Loading is singleton. If a new full screen Loading is invoked before an existing one is closed, the existing full screen Loading instance will be returned instead of actually creating another Loading instance:
 ```javascript

+ 2 - 1
examples/docs/en-US/message-box.md

@@ -380,6 +380,7 @@ The corresponding methods are: `MessageBox`, `MessageBox.alert`, `MessageBox.con
 | type | message type, used for icon display | string | success / info / warning / error | — |
 | customClass | custom class name for MessageBox | string | — | — |
 | callback | MessageBox closing callback if you don't prefer Promise | function(action), where action can be 'confirm' or 'cancel', and `instance` is the MessageBox instance. You can access to that instance's attributes and methods | — | — |
+| showClose | whether to show close icon of MessageBox | boolean | — | true |
 | beforeClose | callback before MessageBox closes, and it will prevent MessageBox from closing | function(action, instance, done), where `action` can be 'confirm' or 'cancel'; `instance` is the MessageBox instance, and you can access to that instance's attributes and methods; `done` is for closing the instance | — | — |
 | lockScroll | whether to lock body scroll when MessageBox prompts | boolean | — | true |
 | showCancelButton | whether to show a cancel button | boolean | — | false (true when called with confirm and prompt) |
@@ -399,4 +400,4 @@ The corresponding methods are: `MessageBox`, `MessageBox.alert`, `MessageBox.con
 | inputValidator | validation function for the input. Should returns a boolean or string. If a string is returned, it will be assigned to inputErrorMessage | function | — | — |
 | inputErrorMessage | error message when validation fails | string | — | Illegal input |
 | center | whether to align the content in center | boolean | — | false |
-| roundButton | whether to use round button | boolean | — | false |
+| roundButton | whether to use round button | boolean | — | false |

+ 13 - 0
examples/docs/en-US/pagination.md

@@ -73,6 +73,18 @@ If you have too much data to display in one page, use pagination.
 ```
 :::
 
+### Buttons with background color
+
+:::demo Set the `background` attribute and the buttons will have a background color.
+```html
+<el-pagination
+  background
+  layout="prev, pager, next"
+  :total="1000">
+</el-pagination>
+```
+:::
+
 ### Small Pagination
 
 Use small pagination in the case of limited space.
@@ -199,6 +211,7 @@ Add more modules based on your scenario.
 | Attribute      | Description          | Type      | Accepted Values       | Default  |
 |--------------------|----------------------------------------------------------|-------------------|-------------|--------|
 | small              |   whether to use small pagination    | boolean |      —       | false |
+| background | whether the buttons have a background color | Boolean | — | false |
 | page-size              | item count of each page  | number |      —       | 10 |
 | total | total item count | number | — | — |
 | page-count | total page count. Set either `total` or `page-count` and pages will be displayed; if you need `page-sizes`, `total` is required | number | — | — |

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

@@ -176,6 +176,7 @@ Vue.use(Radio)
 Vue.use(RadioGroup)
 Vue.use(RadioButton)
 Vue.use(Checkbox)
+Vue.use(CheckboxButton)
 Vue.use(CheckboxGroup)
 Vue.use(Switch)
 Vue.use(Select)

+ 2 - 1
examples/docs/en-US/select.md

@@ -368,7 +368,8 @@ Multiple select uses tags to display selected options.
           value: 'Option5',
           label: 'Option5'
         }],
-        value5: []
+        value5: [],
+        value11: []
       }
     }
   }

+ 2 - 1
examples/docs/en-US/table.md

@@ -1714,7 +1714,7 @@ For table of numbers, you can add an extra row at the table footer displaying ea
 ### Rowspan and colspan
 
 Configuring rowspan and colspan allows you to merge cells
-:::demo Use the `span-method` attribute to configure rowspan and colspan. It accepts a method, and passes an object to that method including current row `row`, current column `column`, current row index `rowIndex` and current column index `columnIndex`. The method should return an array of two numbers, the first number being `rowspan` and second `colspan`. It can also return an object with `rowsapn` and `colspan` props.
+:::demo Use the `span-method` attribute to configure rowspan and colspan. It accepts a method, and passes an object to that method including current row `row`, current column `column`, current row index `rowIndex` and current column index `columnIndex`. The method should return an array of two numbers, the first number being `rowspan` and second `colspan`. It can also return an object with `rowspan` and `colspan` props.
 
 ```html
 <template>
@@ -1990,6 +1990,7 @@ You can customize row index in `type=index` columns.
 | setCurrentRow | used in single selection Table, set a certain row selected. If called without any parameter, it will clear selection. | row |
 | clearSort | clear sorting, restore data to the original order | — |
 | clearFilter | clear filter | — |
+| doLayout | Refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | — |
 
 ### Table Slot
 | Name | Description |

+ 3 - 3
examples/docs/en-US/time-picker.md

@@ -183,13 +183,13 @@ Can pick an arbitrary time range.
 | end-placeholder | placeholder for the end time in range mode | string | — | — |
 | is-range | whether to pick a time range, only works with `<el-time-picker>` | boolean | — | false |
 | arrow-control | whether to pick time using arrow buttons, only works with `<el-time-picker>` | boolean | — | false |
-| value | value of the picker | Date for Time Picker, and string for Time Select | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |
+| value | value of the picker | Date for Time Picker, and string for Time Select | - | - |
 | align | alignment | left / center / right | left |
 | popper-class | custom class name for TimePicker's dropdown | string | — | — |
 | picker-options | additional options, check the table below | object | — | {} |
 | range-separator | range separator | string | - | '-' |
 | default-value | optional, default date of the calendar | Date for TimePicker, string for TimeSelect | anything accepted by `new Date()` for TimePicker, selectable value for TimeSelect | — |
-| value-format | optional, only for TimePicker, format of bounded value | string | hour `HH`, minute `mm`, second `ss` | — |
+| value-format | optional, only for TimePicker, format of bounded value | string | hour `HH`, minute `mm`, second `ss`, AM/PM `A` | — |
 | name | same as `name` in native input | string | — | — |
 
 ### Time Select Options
@@ -205,7 +205,7 @@ Can pick an arbitrary time range.
 | Attribute      | Description          | Type      | Accepted Values       | Default  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | selectableRange | available time range, e.g.`'18:30:00 - 20:30:00'`or`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string / array | — | — |
-| format | format of the picker | string | hour `HH`, minute `mm`, second `ss` | HH:mm:ss |
+| format | format of the picker | string | hour `HH`, minute `mm`, second `ss`, AM/PM `A` | HH:mm:ss |
 
 
 ### Events

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

@@ -1669,6 +1669,7 @@
 | options | 可选项数据源,键名可通过 `props` 属性配置 | array | — | — |
 | props | 配置选项,具体见下表 | object | — | — |
 | value | 选中项绑定值   | array | — | — |
+| separator | 选项分隔符 | string | — | 斜杠'/' |
 | popper-class | 自定义浮层类名   | string | —  | — |
 | placeholder | 输入框占位文本 | string | — | 请选择 |
 | disabled | 是否禁用 | boolean | — | false |

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

@@ -110,7 +110,7 @@
 <el-collapse accordion>
   <el-collapse-item>
     <template slot="title">
-      一致性 Consistency<i class="header-icon el-icon-information"></i>
+      一致性 Consistency<i class="header-icon el-icon-info"></i>
     </template>
     <div>与现实生活一致:与现实生活的流程、逻辑保持一致,遵循用户习惯的语言和概念;</div>
     <div>在界面中一致:所有的元素和结构需保持一致,比如:设计样式、图标和文本、元素的位置等。</div>

+ 6 - 14
examples/docs/zh-CN/date-picker.md

@@ -2,14 +2,9 @@
   module.exports = {
     data() {
       return {
-        pickerOptions0: {
-          disabledDate(time) {
-            return time.getTime() > Date.now();
-          }
-        },
         pickerOptions1: {
           disabledDate(time) {
-            return time.getTime() < Date.now() - 8.64e7;
+            return time.getTime() > Date.now();
           },
           shortcuts: [{
             text: '今天',
@@ -115,8 +110,7 @@
     <el-date-picker
       v-model="value1"
       type="date"
-      placeholder="选择日期"
-      :picker-options="pickerOptions0">
+      placeholder="选择日期">
     </el-date-picker>
   </div>
   <div class="block">
@@ -135,12 +129,10 @@
   export default {
     data() {
       return {
-        pickerOptions0: {
+        pickerOptions1: {
           disabledDate(time) {
             return time.getTime() > Date.now();
-          }
-        },
-        pickerOptions1: {
+          },
           shortcuts: [{
             text: '今天',
             onClick(picker) {
@@ -392,13 +384,13 @@
 | start-placeholder | 范围选择时开始日期的占位内容 | string | — | — |
 | end-placeholder | 范围选择时结束日期的占位内容 | string | — | — |
 | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |
-| format | 显示在输入框中的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd |
+| format | 显示在输入框中的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | yyyy-MM-dd |
 | align | 对齐方式 | string | left, center, right | left |
 | popper-class | DatePicker 下拉框的类名 | string | — | — |
 | picker-options | 当前时间日期选择器特有的选项参考下表 | object |  — | {} |
 | range-separator | 选择范围时的分隔符 | string | — | '-' |
 | default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — |
-| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | — |
+| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | — |
 | name | 原生属性 | string | — | — |
 | unlink-panels | 在范围选择器里取消两个日期面板之间的联动 | boolean | — | false |
 

+ 2 - 2
examples/docs/zh-CN/datetime-picker.md

@@ -246,13 +246,13 @@ DateTimePicker 由 DatePicker 和 TimePicker 派生,`Picker Options` 或者其
 | end-placeholder | 范围选择时结束日期的占位内容 | string | — | — |
 | time-arrow-control | 是否使用箭头进行时间选择 | boolean | — | false |
 | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |
-| format | 显示在输入框中的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd |
+| format | 显示在输入框中的格式 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | yyyy-MM-dd |
 | align | 对齐方式 | string | left, center, right | left |
 | popper-class | DateTimePicker 下拉框的类名 | string | — | — |
 | picker-options | 当前时间日期选择器特有的选项参考下表 | object |  — | {} |
 | range-separator | 选择范围时的分隔符 | string | - | '-' |
 | default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — |
-| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | — |
+| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | — |
 | name | 原生属性 | string | — | — |
 | unlink-panels | 在范围选择器里取消两个日期面板之间的联动 | boolean | — | false |
 

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

@@ -219,6 +219,7 @@ ElementLocale.i18n((key, value) => i18n.t(key, value))
   <li>斯洛文尼亚语(sl)</li>
   <li>阿拉伯语(ar)</li>
   <li>希伯来语(he)</li>
+  <li>立陶宛语(lt)</li>
 </ul>
 
 如果你需要使用其他的语言,欢迎贡献 PR:只需在 [这里](https://github.com/ElemeFE/element/tree/master/src/locale/lang) 添加一个语言配置文件即可。

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

@@ -16,6 +16,7 @@
         input7: '',
         input8: '',
         input9: '',
+        input10: '',
         textarea: '',
         textarea2: '',
         textarea3: '',
@@ -224,6 +225,29 @@ export default {
 ```
 :::
 
+### 可清空
+
+::: demo 使用`clearable`属性即可得到一个可清空的输入框
+
+```html
+<el-input
+  placeholder="请输入内容"
+  v-model="input10"
+  clearable>
+</el-input>
+
+<script>
+  export default {
+    data() {
+      return {
+        input10: ''
+      }
+    }
+  }
+</script>
+```
+:::
+
 ### 带 icon 的输入框
 
 带有图标标记输入类型
@@ -779,6 +803,7 @@ export default {
 | maxlength     | 最大输入长度      | number          |  —  | — |
 | minlength     | 最小输入长度      | number          | — | — |
 | placeholder   | 输入框占位文本    | string          | — | — |
+| clearable     | 是否可清空        | boolean         | — | false |
 | disabled      | 禁用            | boolean         | — | false   |
 | size          | 输入框尺寸,只在 `type!="textarea"` 时有效      | string          | medium / small / mini  | — |
 | prefix-icon   | 输入框头部图标    | string          | — | — |
@@ -799,10 +824,10 @@ export default {
 ### Input slots
 | name | 说明 |
 |------|--------|
-| prefix | 输入框头部内容 |
-| suffix | 输入框尾部内容 |
-| prepend | 输入框前置内容 |
-| append | 输入框后置内容 |
+| prefix | 输入框头部内容,只对 `type="text"` 有效 |
+| suffix | 输入框尾部内容,只对 `type="text"` 有效 |
+| prepend | 输入框前置内容,只对 `type="text"` 有效 |
+| append | 输入框后置内容,只对 `type="text"` 有效 |
 
 ### Input Events
 | 事件名称 | 说明 | 回调参数 |
@@ -831,6 +856,8 @@ export default {
 | name | 原生属性 | string | — | — |
 | select-when-unmatched | 在输入没有任何匹配建议的情况下,按下回车是否触发 `select` 事件 | boolean | — | false |
 | label | 输入框关联的label文字 | string | — | — |
+| prefix-icon | 输入框头部图标 | string | — | — |
+| suffix-icon | 输入框尾部图标 | string | — | — |
 
 ### Autocomplete slots
 | name | 说明 |

+ 3 - 1
examples/docs/zh-CN/loading.md

@@ -231,7 +231,9 @@ Loading.service(options);
 其中 `options` 参数为 Loading 的配置项,具体见下表。`LoadingService` 会返回一个 Loading 实例,可通过调用该实例的 `close` 方法来关闭它:
 ```javascript
 let loadingInstance = Loading.service(options);
-loadingInstance.close();
+this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
+  loadingInstance.close();
+});
 ```
 需要注意的是,以服务的方式调用的全屏 Loading 是单例的:若在前一个全屏 Loading 关闭前再次调用全屏 Loading,并不会创建一个新的 Loading 实例,而是返回现有全屏 Loading 的实例:
 ```javascript

+ 1 - 0
examples/docs/zh-CN/message-box.md

@@ -378,6 +378,7 @@ import { MessageBox } from 'element-ui';
 | type | 消息类型,用于显示图标 | string | success / info / warning / error | — |
 | customClass | MessageBox 的自定义类名 | string | — | — |
 | callback | 若不使用 Promise,可以使用此参数指定 MessageBox 关闭后的回调 | function(action, instance),action 的值为'confirm'或'cancel', instance 为 MessageBox 实例,可以通过它访问实例上的属性和方法 | — | — |
+| showClose | MessageBox 是否显示右上角关闭按钮 | boolean | — | true |
 | beforeClose | MessageBox 关闭前的回调,会暂停实例的关闭 | function(action, instance, done),action 的值为'confirm'或'cancel';instance 为 MessageBox 实例,可以通过它访问实例上的属性和方法;done 用于关闭 MessageBox 实例 | — | — |
 | lockScroll | 是否在 MessageBox 出现时将 body 滚动锁定 | boolean | — | true |
 | showCancelButton | 是否显示取消按钮 | boolean | — | false(以 confirm 和 prompt 方式调用时为 true) |

+ 13 - 0
examples/docs/zh-CN/pagination.md

@@ -23,6 +23,18 @@
 ```
 :::
 
+### 带有背景色的分页
+
+:::demo 设置`background`属性可以为分页按钮添加背景色。
+```html
+<el-pagination
+  background
+  layout="prev, pager, next"
+  :total="1000">
+</el-pagination>
+```
+:::
+
 ### 小型分页
 
 在空间有限的情况下,可以使用简单的小型分页。
@@ -199,6 +211,7 @@
 | 参数               | 说明                                                     | 类型              | 可选值      | 默认值 |
 |--------------------|----------------------------------------------------------|-------------------|-------------|--------|
 | small | 是否使用小型分页样式 | Boolean | — | false |
+| background | 是否为分页按钮添加背景色 | Boolean | — | false |
 | page-size | 每页显示条目个数 | Number | — | 10 |
 | total | 总条目数 | Number | — | — |
 | page-count | 总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性 | Number | — | — |

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

@@ -176,6 +176,7 @@ Vue.use(Radio)
 Vue.use(RadioGroup)
 Vue.use(RadioButton)
 Vue.use(Checkbox)
+Vue.use(CheckboxButton)
 Vue.use(CheckboxGroup)
 Vue.use(Switch)
 Vue.use(Select)

+ 2 - 1
examples/docs/zh-CN/select.md

@@ -367,7 +367,8 @@
           value: '选项5',
           label: '北京烤鸭'
         }],
-        value5: []
+        value5: [],
+        value11: []
       }
     }
   }

+ 2 - 1
examples/docs/zh-CN/table.md

@@ -1777,7 +1777,7 @@
 ### 合并行或列
 
 多行或多列共用一个数据时,可以合并行或列。
-:::demo 通过给`table`传入`span-method`方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行`row`、当前列`column`、当前行号`rowIndex`、当前列号`columnIndex`四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表`rowspan`,第二个元素代表`colspan`。 也可以返回一个键名为`rowsapn`和`colspan`的对象。
+:::demo 通过给`table`传入`span-method`方法可以实现合并行或列,方法的参数是一个对象,里面包含当前行`row`、当前列`column`、当前行号`rowIndex`、当前列号`columnIndex`四个属性。该函数可以返回一个包含两个元素的数组,第一个元素代表`rowspan`,第二个元素代表`colspan`。 也可以返回一个键名为`rowspan`和`colspan`的对象。
 
 ```html
 <template>
@@ -2053,6 +2053,7 @@
 | setCurrentRow | 用于单选表格,设定某一行为选中行,如果调用时不加参数,则会取消目前高亮行的选中状态。 | row |
 | clearSort | 用于清空排序条件,数据会恢复成未排序的状态 | — |
 | clearFilter | 用于清空过滤条件,数据会恢复成未过滤的状态 | — |
+| doLayout | 对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法 | — |
 
 ### Table Slot
 | name | 说明 |

+ 2 - 2
examples/docs/zh-CN/time-picker.md

@@ -189,7 +189,7 @@
 | popper-class | TimePicker 下拉框的类名 | string | — | — |
 | picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} |
 | range-separator | 选择范围时的分隔符 | string | - | '-' |
-| value-format | 可选,仅TimePicker时可用,绑定值的格式,同DatePicker | string | 小时 `HH`,分 `mm`,秒 `ss` | — |
+| value-format | 可选,仅TimePicker时可用,绑定值的格式,同DatePicker | string | 小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | — |
 | default-value | 可选,选择器打开时默认显示的时间 | Date(TimePicker) / string(TimeSelect) | 可被`new Date()`解析(TimePicker) / 可选值(TimeSelect) | — |
 | name | 原生属性 | string | — | — |
 
@@ -206,7 +206,7 @@
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | selectableRange | 可选时间段,例如`'18:30:00 - 20:30:00'`或者传入数组`['09:30:00 - 12:00:00', '14:30:00 - 18:30:00']` | string / array | — | — |
-| format | 时间格式化(TimePicker) | string | 小时:`HH`,分:`mm`,秒:`ss` | 'HH:mm:ss' |
+| format | 时间格式化(TimePicker) | string | 小时:`HH`,分:`mm`,秒:`ss`,AM/PM `A` | 'HH:mm:ss' |
 
 ### Events
 | 事件名 | 说明 | 参数 |

+ 0 - 1
examples/index.tpl

@@ -9,7 +9,6 @@
   </head>
   <body>
     <div id="app"></div><% if (process.env.NODE_ENV === 'production') { %>
-    <!--<script src="https://app.codesponsor.io/scripts/qFcVkt4f3DQEg4zrwINGVg?theme=light&height=250&width=240"></script>-->
     <script>
       if (!window.Promise) {
         document.write('<script src="//shadow.elemecdn.com/npm/es6-promise@4.1.1/dist/es6-promise.min.js"><\/script><script>ES6Promise.polyfill()<\/script>')

+ 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.9":"1.4","2.0.4":"2.0"}
+{"1.4.12":"1.4","2.0.7":"2.0"}

+ 1 - 1
package.json

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

+ 2 - 0
packages/autocomplete/src/autocomplete.vue

@@ -103,6 +103,8 @@
         type: Boolean,
         default: false
       },
+      prefixIcon: String,
+      suffixIcon: String,
       label: String,
       debounce: {
         type: Number,

+ 3 - 1
packages/breadcrumb/src/breadcrumb.vue

@@ -26,7 +26,9 @@
 
     mounted() {
       const items = this.$el.querySelectorAll('.el-breadcrumb__item');
-      items[items.length - 1].setAttribute('aria-current', 'page');
+      if (items.length) {
+        items[items.length - 1].setAttribute('aria-current', 'page');
+      }
     }
   };
 </script>

+ 5 - 1
packages/cascader/src/main.vue

@@ -46,7 +46,7 @@
       <template v-if="showAllLevels">
         <template v-for="(label, index) in currentLabels">
           {{ label }}
-          <span v-if="index < currentLabels.length - 1"> / </span>
+          <span v-if="index < currentLabels.length - 1"> {{ separator }} </span>
         </template>
       </template>
       <template v-else>
@@ -123,6 +123,10 @@ export default {
         return [];
       }
     },
+    separator: {
+      type: String,
+      default: '/'
+    },
     placeholder: {
       type: String,
       default() {

+ 19 - 5
packages/cascader/src/menu.vue

@@ -41,7 +41,8 @@
         expandTrigger: 'click',
         changeOnSelect: false,
         popperClass: '',
-        hoverTimer: 0
+        hoverTimer: 0,
+        clicking: false
       };
     },
 
@@ -148,9 +149,11 @@
 
       let hoverMenuRefs = {};
       const hoverMenuHandler = e => {
+        const activeMenu = hoverMenuRefs.activeMenu;
+        if (!activeMenu) return;
         const offsetX = e.offsetX;
-        const width = hoverMenuRefs.activeMenu.offsetWidth;
-        const height = hoverMenuRefs.activeMenu.offsetHeight;
+        const width = activeMenu.offsetWidth;
+        const height = activeMenu.offsetHeight;
 
         if (e.target === hoverMenuRefs.activeItem) {
           clearTimeout(this.hoverTimer);
@@ -186,7 +189,7 @@
             // keydown up/down/left/right/enter
             events.on.keydown = (ev) => {
               const keyCode = ev.keyCode;
-              if (![37, 38, 39, 40, 13, 9, 27].indexOf(keyCode) > -1) {
+              if ([37, 38, 39, 40, 13, 9, 27].indexOf(keyCode) < 0) {
                 return;
               }
               const currentEle = ev.target;
@@ -228,7 +231,7 @@
                 click: 'click',
                 hover: 'mouseenter'
               }[expandTrigger];
-              events.on[triggerEvent] = events.on['focus'] = () => { // focus 选中
+              const triggerHandler = () => {
                 this.activeItem(item, menuIndex);
                 this.$nextTick(() => {
                   // adjust self and next level
@@ -236,6 +239,17 @@
                   this.scrollMenu(this.$refs.menus[menuIndex + 1]);
                 });
               };
+              events.on[triggerEvent] = triggerHandler;
+              events.on['mousedown'] = () => {
+                this.clicking = true;
+              };
+              events.on['focus'] = () => { // focus 选中
+                if (this.clicking) {
+                  this.clicking = false;
+                  return;
+                }
+                triggerHandler();
+              };
             } else {
               events.on.click = () => {
                 this.select(item, menuIndex);

+ 1 - 1
packages/date-picker/README.md

@@ -44,7 +44,7 @@ C:
 | size          | 输入框尺寸     | string          | large, small, mini  | — |
 | placeholder | 占位内容 | string | — | — |
 | type | 显示类型 | string | year/month/date/week/ datetime/datetimerange/daterange | date |
-| format | 时间日期格式化 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss` | yyyy-MM-dd |
+| format | 时间日期格式化 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | yyyy-MM-dd |
 | align | 对齐方式 | string | left, center, right | left |
 |picker-options | 当前时间日期选择器特有的选项参考下表 | object |  — | {} |
 

+ 15 - 6
packages/date-picker/src/basic/time-spinner.vue

@@ -13,9 +13,8 @@
         <li
           @click="handleClick('hours', { value: hour, disabled: disabled })"
           v-for="(disabled, hour) in hoursList"
-          track-by="hour"
           class="el-time-spinner__item"
-          :class="{ 'active': hour === hours, 'disabled': disabled }">{{ ('0' + hour).slice(-2) }}</li>
+          :class="{ 'active': hour === hours, 'disabled': disabled }">{{ ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) }}{{ amPm(hour) }}</li>
       </el-scrollbar>
       <el-scrollbar
         @mouseenter.native="emitSelectRange('minutes')"
@@ -59,9 +58,7 @@
           <li
             class="el-time-spinner__item"
             :class="{ 'active': hour === hours, 'disabled': hoursList[hour] }"
-            v-for="hour in arrowHourList">
-            {{ hour === undefined ? '' : ('0' + hour).slice(-2) }}
-          </li>
+            v-for="hour in arrowHourList">{{ hour === undefined ? '' : ('0' + (amPmMode ? (hour % 12 || 12) : hour )).slice(-2) + amPm(hour) }}</li>
         </ul>
       </div>
       <div
@@ -116,7 +113,11 @@
         type: Boolean,
         default: true
       },
-      arrowControl: Boolean
+      arrowControl: Boolean,
+      amPmMode: {
+        type: String,
+        default: '' // 'a': am/pm; 'A': AM/PM
+      }
     },
 
     computed: {
@@ -273,6 +274,14 @@
 
         this.modifyDateField(label, now);
         this.adjustSpinner(label, now);
+      },
+      amPm(hour) {
+        let shouldShowAmPm = this.amPmMode.toLowerCase() === 'a';
+        if (!shouldShowAmPm) return '';
+        let isCapital = this.amPmMode === 'A';
+        let content = (hour < 12) ? ' am' : ' pm';
+        if (isCapital) content = content.toUpperCase();
+        return content;
       }
     }
   };

+ 5 - 1
packages/date-picker/src/panel/date-range.vue

@@ -22,6 +22,7 @@
               <span class="el-date-range-picker__time-picker-wrap">
                 <el-input
                   size="small"
+                  :disabled="rangeState.selecting"
                   ref="minInput"
                   :placeholder="t('el.datepicker.startDate')"
                   class="el-date-range-picker__editor"
@@ -32,6 +33,7 @@
               <span class="el-date-range-picker__time-picker-wrap">
                 <el-input
                   size="small"
+                  :disabled="rangeState.selecting"
                   :placeholder="t('el.datepicker.startTime')"
                   class="el-date-range-picker__editor"
                   :value="minVisibleTime"
@@ -51,6 +53,7 @@
               <span class="el-date-range-picker__time-picker-wrap">
                 <el-input
                   size="small"
+                  :disabled="rangeState.selecting"
                   :placeholder="t('el.datepicker.endDate')"
                   class="el-date-range-picker__editor"
                   :value="maxVisibleDate"
@@ -61,6 +64,7 @@
               <span class="el-date-range-picker__time-picker-wrap">
                 <el-input
                   size="small"
+                  :disabled="rangeState.selecting"
                   ref="maxInput"
                   :placeholder="t('el.datepicker.endTime')"
                   class="el-date-range-picker__editor"
@@ -508,7 +512,7 @@
           this.minTimePickerVisible = visible;
         }
 
-        if (this.maxDate && this.maxDate.getTime() < this.minDate.getTime()) {
+        if (!this.maxDate || this.maxDate && this.maxDate.getTime() < this.minDate.getTime()) {
           this.maxDate = new Date(this.minDate);
         }
       },

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

@@ -514,7 +514,7 @@
 
       dateFormat() {
         if (this.format) {
-          return this.format.replace('HH', '').replace(':mm', '').replace(':ss', '').trim();
+          return this.format.replace('HH', '').replace(/[^a-zA-Z]*mm/, '').replace(/[^a-zA-Z]*ss/, '').trim();
         } else {
           return 'yyyy-MM-dd';
         }

+ 7 - 0
packages/date-picker/src/panel/time-range.vue

@@ -15,6 +15,7 @@
             <time-spinner
               ref="minSpinner"
               :show-seconds="showSeconds"
+              :am-pm-mode="amPmMode"
               @change="handleMinChange"
               :arrow-control="arrowControl"
               @select-range="setMinSelectionRange"
@@ -30,6 +31,7 @@
             <time-spinner
               ref="maxSpinner"
               :show-seconds="showSeconds"
+              :am-pm-mode="amPmMode"
               @change="handleMaxChange"
               :arrow-control="arrowControl"
               @select-range="setMaxSelectionRange"
@@ -100,6 +102,11 @@
 
       btnDisabled() {
         return this.minDate.getTime() > this.maxDate.getTime();
+      },
+      amPmMode() {
+        if ((this.format || '').indexOf('A') !== -1) return 'A';
+        if ((this.format || '').indexOf('a') !== -1) return 'a';
+        return '';
       }
     },
 

+ 6 - 0
packages/date-picker/src/panel/time.vue

@@ -10,6 +10,7 @@
           @change="handleChange"
           :arrow-control="useArrow"
           :show-seconds="showSeconds"
+          :am-pm-mode="amPmMode"
           @select-range="setSelectionRange"
           :date="date">
         </time-spinner>
@@ -104,6 +105,11 @@
       },
       useArrow() {
         return this.arrowControl || this.timeArrowControl || false;
+      },
+      amPmMode() {
+        if ((this.format || '').indexOf('A') !== -1) return 'A';
+        if ((this.format || '').indexOf('a') !== -1) return 'a';
+        return '';
       }
     },
 

+ 0 - 1
packages/dialog/src/component.vue

@@ -107,7 +107,6 @@
 
     watch: {
       visible(val) {
-        this.$emit('update:visible', val);
         if (val) {
           this.closed = false;
           this.$emit('open');

+ 1 - 1
packages/dropdown/src/dropdown-menu.vue

@@ -24,7 +24,7 @@
 
     data() {
       return {
-        size: this.dropdown.size
+        size: this.dropdown.dropdownSize
       };
     },
 

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

@@ -128,7 +128,11 @@
       },
       handleClick() {
         if (this.triggerElm.disabled) return;
-        this.visible = !this.visible;
+        if (this.visible) {
+          this.hide();
+        } else {
+          this.show();
+        }
       },
       handleTriggerKeyDown(ev) {
         const keyCode = ev.keyCode;
@@ -194,7 +198,7 @@
         if (!this.splitButton) { // 自定义
           this.triggerElm.setAttribute('role', 'button');
           this.triggerElm.setAttribute('tabindex', '0');
-          this.triggerElm.className += ' el-dropdown-selfdefine'; // 控制
+          this.triggerElm.setAttribute('class', this.triggerElm.getAttribute('class') + ' el-dropdown-selfdefine'); // 控制
         }
       },
       initEvent() {

+ 5 - 0
packages/form/src/form-item.vue

@@ -176,6 +176,11 @@
         this.validateState = 'validating';
 
         var descriptor = {};
+        if (rules && rules.length > 0) {
+          rules.forEach(rule => {
+            delete rule.trigger;
+          });
+        }
         descriptor[this.prop] = rules;
 
         var validator = new AsyncValidator(descriptor);

+ 40 - 12
packages/input/src/input.vue

@@ -10,7 +10,10 @@
       'el-input--prefix': $slots.prefix || prefixIcon,
       'el-input--suffix': $slots.suffix || suffixIcon
     }
-  ]">
+    ]"
+    @mouseenter="hovering = true"
+    @mouseleave="hovering = false"
+  >
     <template v-if="type !== 'textarea'">
       <!-- 前置元素 -->
       <div class="el-input-group__prepend" v-if="$slots.prepend"  tabindex="0">
@@ -40,14 +43,20 @@
       <!-- 后置内容 -->
       <span
         class="el-input__suffix"
-        v-if="$slots.suffix || suffixIcon || validateState && needStatusIcon"
+        v-if="$slots.suffix || suffixIcon || showClear || validateState && needStatusIcon"
         :style="suffixOffset">
         <span class="el-input__suffix-inner">
-          <slot name="suffix"></slot>
-          <i class="el-input__icon"
-            v-if="suffixIcon"
-            :class="suffixIcon">
-          </i>
+          <template v-if="!showClear">
+            <slot name="suffix"></slot>
+            <i class="el-input__icon"
+              v-if="suffixIcon"
+              :class="suffixIcon">
+            </i>
+          </template>
+          <i v-else
+            class="el-input__icon el-icon-circle-close el-input__clear"
+            @click="clear"
+          ></i>
         </span>
         <i class="el-input__icon"
           v-if="validateState"
@@ -77,7 +86,6 @@
 </template>
 <script>
   import emitter from 'element-ui/src/mixins/emitter';
-  import Focus from 'element-ui/src/mixins/focus';
   import Migrating from 'element-ui/src/mixins/migrating';
   import calcTextareaHeight from './calcTextareaHeight';
   import merge from 'element-ui/src/utils/merge';
@@ -87,7 +95,7 @@
 
     componentName: 'ElInput',
 
-    mixins: [emitter, Focus('input'), Migrating],
+    mixins: [emitter, Migrating],
 
     inject: {
       elForm: {
@@ -103,7 +111,9 @@
         currentValue: this.value,
         textareaCalcStyle: {},
         prefixOffset: null,
-        suffixOffset: null
+        suffixOffset: null,
+        hovering: false,
+        focused: false
       };
     },
 
@@ -145,7 +155,11 @@
       },
       suffixIcon: String,
       prefixIcon: String,
-      label: String
+      label: String,
+      clearable: {
+        type: Boolean,
+        default: false
+      }
     },
 
     computed: {
@@ -173,6 +187,9 @@
       },
       isGroup() {
         return this.$slots.prepend || this.$slots.append;
+      },
+      showClear() {
+        return this.clearable && this.currentValue !== '' && (this.focused || this.hovering);
       }
     },
 
@@ -183,6 +200,9 @@
     },
 
     methods: {
+      focus() {
+        (this.$refs.input || this.$refs.textarea).focus();
+      },
       getMigratingConfig() {
         return {
           props: {
@@ -195,13 +215,14 @@
         };
       },
       handleBlur(event) {
+        this.focused = false;
         this.$emit('blur', event);
         if (this.validateEvent) {
           this.dispatch('ElFormItem', 'el.form.blur', [this.currentValue]);
         }
       },
       inputSelect() {
-        this.$refs.input.select();
+        (this.$refs.input || this.$refs.textarea).select();
       },
       resizeTextarea() {
         if (this.$isServer) return;
@@ -219,6 +240,7 @@
         this.textareaCalcStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows);
       },
       handleFocus(event) {
+        this.focused = true;
         this.$emit('focus', event);
       },
       handleInput(event) {
@@ -250,6 +272,12 @@
         if (this.$slots[pendant]) {
           return { transform: `translateX(${place === 'suf' ? '-' : ''}${this.$el.querySelector(`.el-input-group__${pendant}`).offsetWidth}px)` };
         }
+      },
+      clear() {
+        this.$emit('input', '');
+        this.$emit('change', '');
+        this.setCurrentValue('');
+        this.focus();
       }
     },
 

+ 4 - 2
packages/menu/src/menu.vue

@@ -119,7 +119,7 @@
     data() {
       return {
         activeIndex: this.defaultActive,
-        openedMenus: this.defaultOpeneds ? this.defaultOpeneds.slice(0) : [],
+        openedMenus: (this.defaultOpeneds && !this.collapse) ? this.defaultOpeneds.slice(0) : [],
         items: {},
         submenus: {}
       };
@@ -141,7 +141,9 @@
 
       },
       defaultOpeneds(value) {
-        this.openedMenus = value;
+        if (!this.collapse) {
+          this.openedMenus = value;
+        }
       },
       collapse(value) {
         if (value) this.openedMenus = [];

+ 1 - 0
packages/message-box/src/main.js

@@ -204,6 +204,7 @@ MessageBox.prompt = (message, title, options) => {
 };
 
 MessageBox.close = () => {
+  instance.doClose();
   instance.visible = false;
   msgQueue = [];
   currentMsg = null;

+ 10 - 6
packages/message-box/src/main.vue

@@ -216,7 +216,7 @@
           var inputPattern = this.inputPattern;
           if (inputPattern && !inputPattern.test(this.inputValue || '')) {
             this.editorErrorMessage = this.inputErrorMessage || t('el.messagebox.error');
-            addClass(this.$refs.input.$el.querySelector('input'), 'invalid');
+            addClass(this.getInputElement(), 'invalid');
             return false;
           }
           var inputValidator = this.inputValidator;
@@ -224,7 +224,7 @@
             var validateResult = inputValidator(this.inputValue);
             if (validateResult === false) {
               this.editorErrorMessage = this.inputErrorMessage || t('el.messagebox.error');
-              addClass(this.$refs.input.$el.querySelector('input'), 'invalid');
+              addClass(this.getInputElement(), 'invalid');
               return false;
             }
             if (typeof validateResult === 'string') {
@@ -234,13 +234,17 @@
           }
         }
         this.editorErrorMessage = '';
-        removeClass(this.$refs.input.$el.querySelector('input'), 'invalid');
+        removeClass(this.getInputElement(), 'invalid');
         return true;
       },
       getFistFocus() {
         const $btns = this.$el.querySelector('.el-message-box__btns .el-button');
         const $title = this.$el.querySelector('.el-message-box__btns .el-message-box__title');
         return $btns && $btns[0] || $title;
+      },
+      getInputElement() {
+        const inputRefs = this.$refs.input.$refs;
+        return inputRefs.input || inputRefs.textarea;
       }
     },
 
@@ -266,19 +270,19 @@
           }
           this.focusAfterClosed = document.activeElement;
           messageBox = new Dialog(this.$el, this.focusAfterClosed, this.getFistFocus());
-        };
+        }
 
         // prompt
         if (this.$type !== 'prompt') return;
         if (val) {
           setTimeout(() => {
             if (this.$refs.input && this.$refs.input.$el) {
-              this.$refs.input.$el.querySelector('input').focus();
+              this.getInputElement().focus();
             }
           }, 500);
         } else {
           this.editorErrorMessage = '';
-          removeClass(this.$refs.input.$el.querySelector('input'), 'invalid');
+          removeClass(this.getInputElement(), 'invalid');
         }
       }
     },

+ 25 - 20
packages/pagination/src/pagination.js

@@ -40,7 +40,9 @@ export default {
 
     prevText: String,
 
-    nextText: String
+    nextText: String,
+
+    background: Boolean
   },
 
   data() {
@@ -51,7 +53,10 @@ export default {
   },
 
   render(h) {
-    let template = <div class='el-pagination'></div>;
+    let template = <div class={['el-pagination', {
+      'is-background': this.background,
+      'el-pagination--small': this.small
+    }] }></div>;
     const layout = this.layout || '';
     if (!layout) return;
     const TEMPLATE_MAP = {
@@ -67,10 +72,6 @@ export default {
     const rightWrapper = <div class="el-pagination__rightwrapper"></div>;
     let haveRightWrapper = false;
 
-    if (this.small) {
-      template.data.class += ' el-pagination--small';
-    }
-
     components.forEach(compo => {
       if (compo === '->') {
         haveRightWrapper = true;
@@ -210,23 +211,27 @@ export default {
           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(event.target.value);
-          }
+          this.resetValueIfNeed(target.value);
+          this.reassignMaxValue(target.value);
         },
         handleChange(value) {
           this.$parent.internalCurrentPage = this.$parent.getValidCurrentPage(value);
           this.oldValue = null;
+          this.resetValueIfNeed(value);
+        },
+        resetValueIfNeed(value) {
+          const num = parseInt(value, 10);
+          if (!isNaN(num)) {
+            if (num < 1) {
+              this.$refs.input.$el.querySelector('input').value = 1;
+            } else {
+              this.reassignMaxValue(value);
+            }
+          }
         },
-        reassignMaxValue(target) {
-          if (+target.value > this.$parent.internalPageCount) {
-            target.value = this.$parent.internalPageCount;
+        reassignMaxValue(value) {
+          if (+value > this.$parent.internalPageCount) {
+            this.$refs.input.$el.querySelector('input').value = this.$parent.internalPageCount;
           }
         }
       },
@@ -242,10 +247,10 @@ export default {
               value={ this.$parent.internalCurrentPage }
               domPropsValue={ this.$parent.internalCurrentPage }
               type="number"
+              ref="input"
               onChange={ this.handleChange }
               onFocus={ this.handleFocus }
-              onBlur={ this.handleBlur }
-              nativeOnKeyup={ this.handleKeyUp }/>
+              onBlur={ this.handleBlur }/>
             { this.t('el.pagination.pageClassifier') }
           </span>
         );

+ 3 - 3
packages/popover/src/main.vue

@@ -131,14 +131,14 @@ export default {
     },
     handleFocus() {
       addClass(this.referenceElm, 'focusing');
-      this.showPopper = true;
+      if (this.trigger !== 'manual') this.showPopper = true;
     },
     handleClick() {
       removeClass(this.referenceElm, 'focusing');
     },
     handleBlur() {
       removeClass(this.referenceElm, 'focusing');
-      this.showPopper = false;
+      if (this.trigger !== 'manual') this.showPopper = false;
     },
     handleMouseEnter() {
       clearTimeout(this._timer);
@@ -151,7 +151,7 @@ export default {
       }
     },
     handleKeydown(ev) {
-      if (ev.keyCode === 27) { // esc
+      if (ev.keyCode === 27 && this.trigger !== 'manual') { // esc
         this.doClose();
       }
     },

+ 1 - 1
packages/select/src/option.vue

@@ -74,7 +74,7 @@
       limitReached() {
         if (this.select.multiple) {
           return !this.itemSelected &&
-            this.select.value.length >= this.select.multipleLimit &&
+            (this.select.value || []).length >= this.select.multipleLimit &&
             this.select.multipleLimit > 0;
         } else {
           return false;

+ 8 - 4
packages/select/src/select.vue

@@ -11,6 +11,7 @@
       :style="{ 'max-width': inputWidth - 32 + 'px' }">
       <span
         class="el-select__multiple-text"
+        v-show="multipleText"
         v-if="collapseTags">
         {{ multipleText }}
       </span>
@@ -65,8 +66,8 @@
       @blur="handleBlur"
       @mousedown.native="handleMouseDown"
       @keyup.native="debouncedOnInputChange"
-      @keydown.native.down.prevent="navigateOptions('next')"
-      @keydown.native.up.prevent="navigateOptions('prev')"
+      @keydown.native.down.stop.prevent="navigateOptions('next')"
+      @keydown.native.up.stop.prevent="navigateOptions('prev')"
       @keydown.native.enter.prevent="selectOption"
       @keydown.native.esc.stop.prevent="visible = false"
       @keydown.native.tab="visible = false"
@@ -89,6 +90,7 @@
           tag="ul"
           wrap-class="el-select-dropdown__wrap"
           view-class="el-select-dropdown__list"
+          ref="scrollbar"
           :class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"
           v-show="options.length > 0 && !loading">
           <el-option
@@ -375,7 +377,8 @@
         });
         this.hoverIndex = -1;
         if (this.multiple && this.filterable) {
-          this.inputLength = this.$refs.input.value.length * 15 + 20;
+          const length = this.$refs.input.value.length * 15 + 20;
+          this.inputLength = this.collapseTags ? Math.min(50, length) : length;
           this.managePlaceholder();
           this.resetInputHeight();
         }
@@ -415,6 +418,7 @@
           const menu = this.$refs.popper.$el.querySelector('.el-select-dropdown__wrap');
           scrollIntoView(menu, target);
         }
+        this.$refs.scrollbar && this.$refs.scrollbar.handleScroll();
       },
 
       handleMenuEnter() {
@@ -556,7 +560,7 @@
           let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0];
           const tags = this.$refs.tags;
           input.style.height = this.selected.length === 0
-            ? sizeMap[this.selectSize] + 'px'
+            ? (sizeMap[this.selectSize] || 40) + 'px'
             : Math.max(tags ? (tags.clientHeight + 10) : 0, sizeMap[this.selectSize] || 40) + 'px';
           if (this.visible && this.emptyText !== false) {
             this.broadcast('ElSelectDropdown', 'updatePopper');

+ 6 - 4
packages/table/src/table-body.js

@@ -138,7 +138,8 @@ export default {
       if (!this.store.states.isComplex) return;
       const el = this.$el;
       if (!el) return;
-      const rows = el.querySelectorAll('tbody > tr.el-table__row');
+      const tr = el.querySelector('tbody').children;
+      const rows = [].filter.call(tr, row => hasClass(row, 'el-table__row'));
       const oldRow = rows[oldVal];
       const newRow = rows[newVal];
       if (oldRow) {
@@ -153,7 +154,8 @@ export default {
       const el = this.$el;
       if (!el) return;
       const data = this.store.states.data;
-      const rows = el.querySelectorAll('tbody > tr.el-table__row');
+      const tr = el.querySelector('tbody').children;
+      const rows = [].filter.call(tr, row => hasClass(row, 'el-table__row'));
       const oldRow = rows[data.indexOf(oldVal)];
       const newRow = rows[data.indexOf(newVal)];
       if (oldRow) {
@@ -340,10 +342,10 @@ export default {
       // 判断是否text-overflow, 如果是就显示tooltip
       const cellChild = event.target.querySelector('.cell');
 
-      if (hasClass(cellChild, 'el-tooltip') && cellChild.scrollWidth > cellChild.offsetWidth) {
+      if (hasClass(cellChild, 'el-tooltip') && cellChild.scrollWidth > cellChild.offsetWidth && this.$refs.tooltip) {
         const tooltip = this.$refs.tooltip;
 
-        this.tooltipContent = cell.innerText;
+        this.tooltipContent = cell.textContent || cell.innerText;
         tooltip.referenceElm = cell;
         tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none');
         tooltip.doDestroy();

+ 2 - 2
packages/table/src/table-column.js

@@ -65,8 +65,8 @@ const forced = {
     sortable: false
   },
   expand: {
-    renderHeader: function(h, {}) {
-      return '';
+    renderHeader: function(h, { column }) {
+      return column.label || '';
     },
     renderCell: function(h, { row, store }, proxy) {
       const expanded = store.states.expandRows.indexOf(row) > -1;

+ 6 - 11
packages/table/src/table.vue

@@ -345,7 +345,6 @@
         this.updateScrollY();
         this.layout.update();
         this.$nextTick(() => {
-          if (this.destroyed) return;
           if (this.height) {
             this.layout.setHeight(this.height);
           } else if (this.maxHeight) {
@@ -353,12 +352,6 @@
           } else if (this.shouldUpdateHeight) {
             this.layout.updateHeight();
           }
-          if (this.$el) {
-            this.isHidden = this.$el.clientWidth === 0;
-            if (this.isHidden && this.layout.bodyWidth) {
-              setTimeout(() => this.debouncedLayout());
-            }
-          }
         });
       }
     },
@@ -482,7 +475,11 @@
         immediate: true,
         handler(val) {
           this.store.commit('setData', val);
-          if (this.$ready) this.doLayout();
+          if (this.$ready) {
+            this.$nextTick(() => {
+              this.doLayout();
+            });
+          }
         }
       },
 
@@ -497,7 +494,6 @@
     },
 
     destroyed() {
-      this.destroyed = true;
       if (this.windowResizeListener) removeResizeListener(this.$el, this.windowResizeListener);
     },
 
@@ -538,8 +534,7 @@
         resizeProxyVisible: false,
         // 是否拥有多级表头
         isGroup: false,
-        scrollPosition: 'left',
-        destroyed: false
+        scrollPosition: 'left'
       };
     }
   };

+ 1 - 1
packages/tag/src/tag.vue

@@ -11,7 +11,7 @@
       <slot></slot>
       <i class="el-tag__close el-icon-close"
         v-if="closable"
-        @click="handleClose"></i>
+        @click.stop="handleClose"></i>
     </span>
   </transition>
 </template>

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

@@ -1,6 +1,6 @@
 {
   "name": "element-theme-chalk",
-  "version": "2.0.4",
+  "version": "2.0.7",
   "description": "Element component chalk theme.",
   "main": "lib/index.css",
   "style": "lib/index.css",

+ 7 - 1
packages/theme-chalk/src/button.scss

@@ -142,7 +142,7 @@
     @include button-size($--button-mini-padding-vertical, $--button-mini-padding-horizontal, $--button-mini-font-size, $--button-mini-border-radius);
   }
   @include m(text) {
-    border: none;
+    border-color: transparent;
     color: $--color-primary;
     background: transparent;
     padding-left: 0;
@@ -159,6 +159,12 @@
       border-color: transparent;
       background-color: transparent;
     }
+
+    &.is-disabled,
+    &.is-disabled:hover,
+    &.is-disabled:focus {
+      border-color: transparent;
+    }
   }
 }
 

+ 3 - 2
packages/theme-chalk/src/common/var.scss

@@ -25,8 +25,8 @@ $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /
 $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
 $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
 
-$--color-success: #67c23a !default;
-$--color-warning: #eb9e05 !default;
+$--color-success: #5cb87a !default;
+$--color-warning: #e6a23c !default;
 $--color-danger: #fa5555 !default;
 $--color-info: #878d99 !default;
 
@@ -329,6 +329,7 @@ $--input-placeholder-color: $--color-text-placeholder !default;
 $--input-max-width: 314px !default;
 
 $--input-hover-border: $--border-color-hover !default;
+$--input-clear-hover-color: $--color-text-secondary !default;
 
 $--input-focus-border: $--color-primary !default;
 $--input-focus-fill: $--color-white !default;

BIN
packages/theme-chalk/src/fonts/element-icons.ttf


BIN
packages/theme-chalk/src/fonts/element-icons.woff


+ 2 - 2
packages/theme-chalk/src/icon.scss

@@ -2,8 +2,8 @@
 
 @font-face {
   font-family: 'element-icons';
-  src: url('#{$--font-path}/element-icons.woff?t=1508751886602') format('woff'), /* chrome, firefox */
-       url('#{$--font-path}/element-icons.ttf?t=1508751886602') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+  src: url('#{$--font-path}/element-icons.woff?t=1510834658947') format('woff'), /* chrome, firefox */
+       url('#{$--font-path}/element-icons.ttf?t=1510834658947') format('truetype'); /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
   font-weight: normal;
   font-style: normal
 }

+ 12 - 0
packages/theme-chalk/src/input.scss

@@ -8,6 +8,18 @@
   width: 100%;
   @include scroll-bar;
 
+  & .el-input__clear {
+    color: $--input-icon-color;
+    font-size: $--input-font-size;
+    line-height: 16px;
+    cursor: pointer;
+    transition: $--color-transition-base;
+
+    &:hover {
+      color: $--input-clear-hover-color;
+    }
+  }
+
   @include e(inner) {
     -webkit-appearance: none;
     background-color: $--input-fill;

+ 1 - 0
packages/theme-chalk/src/menu.scss

@@ -171,6 +171,7 @@
     width: 24px;
     text-align: center;
     font-size: 18px;
+    vertical-align: middle;
   }
   & * {
     vertical-align: middle;

+ 43 - 2
packages/theme-chalk/src/pagination.scss

@@ -75,6 +75,7 @@
     .el-icon {
       display: block;
       font-size: 12px;
+      font-weight: bold;
     }
   }
 
@@ -162,6 +163,46 @@
       margin: 0;
     }
   }
+
+  @include when(background) {
+    .btn-prev,
+    .btn-next,
+    .el-pager li {
+      margin: 0 5px;
+      background-color: $--color-info-lighter;
+      color: $--color-text-regular;
+      min-width: 30px;
+      border-radius: 2px;
+    }
+
+    .btn-prev, .btn-next {
+      padding: 0;
+
+      &.disabled {
+        color: $--color-text-placeholder;
+      }
+    }
+
+    .el-pager li {
+      &:hover {
+        color: $--pagination-hover-fill;
+      }
+
+      &.active {
+        background-color: $--color-primary;
+        color: $--color-white;
+      }
+    }
+
+    &.el-pagination--small {
+      .btn-prev,
+      .btn-next,
+      .el-pager li {
+        margin: 0 3px;
+        min-width: 22px;
+      }
+    }
+  }
 }
 
 @include b(pager) {
@@ -173,8 +214,8 @@
   padding: 0;
   margin: 0;
 
-  .el-icon-more::before {
-    vertical-align: -4px;
+  .more::before {
+    line-height: 30px;
   }
 
   li {

+ 1 - 1
packages/theme-chalk/src/select.scss

@@ -93,7 +93,7 @@
     margin-left: 15px;
     color: $--input-color;
     font-size: $--font-size-base;
-    display: block;
+    display: inline;
     @include utils-ellipsis;
   }
 

+ 8 - 6
packages/theme-chalk/src/table.scss

@@ -426,12 +426,15 @@
   }
 
   .caret-wrapper {
-    position: absolute;
-    display: inline-block;
-    height: 100%;
+    display: inline-flex;
+    flex-direction: column;
+    align-items: center;
+    height: 34px;
+    width: 24px;
     vertical-align: middle;
     cursor: pointer;
     overflow: initial;
+    position: relative;
   }
 
   .sort-caret {
@@ -440,14 +443,13 @@
     overflow: hidden;
     font-size: 15px;
     position: absolute;
-    left: 4px;
 
     &.ascending {
-      top: 1px;
+      top: 5px;
     }
 
     &.descending {
-      bottom: 1px;
+      bottom: 7px;
     }
   }
 

+ 3 - 3
packages/theme-chalk/src/tag.scss

@@ -20,9 +20,9 @@
     position: relative;
     cursor: pointer;
     font-size: 12px;
-    height: 18px;
-    width: 18px;
-    line-height: 18px;
+    height: 16px;
+    width: 16px;
+    line-height: 16px;
     vertical-align: middle;
     top: -1px;
     right: -5px;

+ 3 - 2
packages/tooltip/src/main.js

@@ -1,5 +1,6 @@
 import Popper from 'element-ui/src/utils/vue-popper';
 import debounce from 'throttle-debounce/debounce';
+import { addClass, removeClass } from 'element-ui/src/utils/dom';
 import { getFirstComponentChild } from 'element-ui/src/utils/vdom';
 import { generateId } from 'element-ui/src/utils/util';
 import Vue from 'vue';
@@ -122,9 +123,9 @@ export default {
   watch: {
     focusing(val) {
       if (val) {
-        this.referenceElm.className += ' focusing';
+        addClass(this.referenceElm, 'focusing');
       } else {
-        this.referenceElm.className = this.referenceElm.className.replace('focusing', '');
+        removeClass(this.referenceElm, 'focusing');
       }
     }
   },

+ 3 - 3
packages/tree/src/tree.vue

@@ -194,10 +194,12 @@
           checkedItem[0].setAttribute('tabindex', 0);
           return;
         }
-        this.treeItems[0].setAttribute('tabindex', 0);
+        this.treeItems[0] && this.treeItems[0].setAttribute('tabindex', 0);
       },
       handelKeydown(ev) {
         const currentItem = ev.target;
+        if (currentItem.className.indexOf('el-tree-node') === -1) return;
+        ev.preventDefault();
         const keyCode = ev.keyCode;
         this.treeItems = this.$el.querySelectorAll('.is-focusable[role=treeitem]');
         const currentIndex = this.treeItemArray.indexOf(currentItem);
@@ -218,8 +220,6 @@
           if (hasInput) {
             hasInput.click();
           }
-          ev.stopPropagation();
-          ev.preventDefault();
         }
       }
     },

+ 1 - 3
src/index.js

@@ -142,8 +142,6 @@ const components = [
 ];
 
 const install = function(Vue, opts = {}) {
-  /* istanbul ignore if */
-  if (install.installed) return;
   locale.use(opts.locale);
   locale.i18n(opts.i18n);
 
@@ -173,7 +171,7 @@ if (typeof window !== 'undefined' && window.Vue) {
 };
 
 module.exports = {
-  version: '2.0.4',
+  version: '2.0.7',
   locale: locale.use,
   i18n: locale.i18n,
   install,

+ 11 - 11
src/locale/lang/en.js

@@ -21,18 +21,18 @@ export default {
       prevMonth: 'Previous Month',
       nextMonth: 'Next Month',
       year: '',
-      month1: 'Jan',
-      month2: 'Feb',
-      month3: 'Mar',
-      month4: 'Apr',
+      month1: 'January',
+      month2: 'February',
+      month3: 'March',
+      month4: 'April',
       month5: 'May',
-      month6: 'Jun',
-      month7: 'Jul',
-      month8: 'Aug',
-      month9: 'Sep',
-      month10: 'Oct',
-      month11: 'Nov',
-      month12: 'Dec',
+      month6: 'June',
+      month7: 'July',
+      month8: 'August',
+      month9: 'September',
+      month10: 'October',
+      month11: 'November',
+      month12: 'December',
       // week: 'week',
       weeks: {
         sun: 'Sun',

+ 10 - 10
src/locale/lang/fa.js

@@ -2,24 +2,24 @@ export default {
   el: {
     colorpicker: {
       confirm: 'باشد',
-      clear: 'خذف'
+      clear: 'حذف'
     },
     datepicker: {
       now: 'اکنون',
       today: 'امروز',
       cancel: 'لغو',
-      clear: 'خذف',
-      confirm: 'باشد',
+      clear: 'حذف',
+      confirm: 'باشه',
       selectDate: 'انتخاب تاریخ',
       selectTime: 'انتخاب زمان',
       startDate: 'تاریخ شروع',
       startTime: 'زمان شروع',
       endDate: 'تاریخ پایان',
       endTime: 'زمان پایان',
-      prevYear: 'Previous Year', // to be translated
-      nextYear: 'Next Year', // to be translated
-      prevMonth: 'Previous Month', // to be translated
-      nextMonth: 'Next Month', // to be translated
+      prevYear: 'سال قبل',
+      nextYear: 'سال بعد',
+      prevMonth: 'ماه قبل',
+      nextMonth: 'ماه بعد',
       year: 'سال',
       month1: 'ژانویه',
       month2: 'فوریه',
@@ -77,7 +77,7 @@ export default {
     },
     messagebox: {
       title: 'پیام',
-      confirm: 'باشد',
+      confirm: 'باشه',
       cancel: 'لغو',
       error: 'ورودی غیر مجاز'
     },
@@ -85,7 +85,7 @@ export default {
       deleteTip: 'press delete to remove', // to be translated
       delete: 'حذف',
       preview: 'پیش‌نمایش',
-      continue: 'ادهمه'
+      continue: 'ادامه'
     },
     table: {
       emptyText: 'اطلاعاتی وجود ندارد',
@@ -101,7 +101,7 @@ export default {
       noMatch: 'هیچ داده‌ای پیدا نشد',
       noData: 'اطلاعاتی وجود ندارد',
       titles: ['List 1', 'List 2'], // to be translated
-      filterPlaceholder: 'Enter keyword', // to be translated
+      filterPlaceholder: 'کلید واژه هارو وارد کن',
       noCheckedFormat: '{total} items', // to be translated
       hasCheckedFormat: '{checked}/{total} checked' // to be translated
     }

+ 5 - 5
src/locale/lang/ko.js

@@ -16,10 +16,10 @@ export default {
       startTime: '시작 시간',
       endDate: '종료 날짜',
       endTime: '종료 시간',
-      prevYear: 'Previous Year', // to be translated
-      nextYear: 'Next Year', // to be translated
-      prevMonth: 'Previous Month', // to be translated
-      nextMonth: 'Next Month', // to be translated
+      prevYear: '지난해',
+      nextYear: '다음해',
+      prevMonth: '지난달',
+      nextMonth: '다음달',
       year: '년',
       month1: '1월',
       month2: '2월',
@@ -82,7 +82,7 @@ export default {
       error: '올바르지 않은 입력'
     },
     upload: {
-      deleteTip: 'press delete to remove', // to be translated
+      deleteTip: '클릭시 삭제됩니다',
       delete: '삭제',
       preview: '미리보기',
       continue: '계속하기'

+ 109 - 0
src/locale/lang/kz.js

@@ -0,0 +1,109 @@
+export default {
+  el: {
+    colorpicker: {
+      confirm: 'Қабылдау',
+      clear: 'Тазалау'
+    },
+    datepicker: {
+      now: 'Қазір',
+      today: 'Бүгін',
+      cancel: 'Болдырмау',
+      clear: 'Тазалау',
+      confirm: 'Қабылдау',
+      selectDate: 'Күнді таңдаңыз',
+      selectTime: 'Сағатты таңдаңыз',
+      startDate: 'Басталу күні',
+      startTime: 'Басталу сағаты',
+      endDate: 'Аяқталу күні',
+      endTime: 'Аяқталу сағаты',
+      prevYear: 'Алдыңғы жыл',
+      nextYear: 'Келесі жыл',
+      prevMonth: 'Алдыңғы ай',
+      nextMonth: 'Келесі ай',
+      year: 'Жыл',
+      month1: 'Қаңтар',
+      month2: 'Ақпан',
+      month3: 'Наурыз',
+      month4: 'Сәуір',
+      month5: 'Мамыр',
+      month6: 'Маусым',
+      month7: 'Шілде',
+      month8: 'Тамыз',
+      month9: 'Қыркүйек',
+      month10: 'Қазан',
+      month11: 'Қараша',
+      month12: 'Желтоқсан',
+      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: {
+      deleteTip: 'Өшіруді басып өшіріңіз',
+      delete: 'Өшіру',
+      preview: 'Алдын ала қарау',
+      continue: 'Жалғастыру'
+    },
+    table: {
+      emptyText: 'Деректер жоқ',
+      confirmFilter: 'Қабылдау',
+      resetFilter: 'Қалпына келтіру',
+      clearFilter: 'Барлығы',
+      sumText: 'Сомасы'
+    },
+    tree: {
+      emptyText: 'Деректер жоқ'
+    },
+    transfer: {
+      noMatch: 'Сәйкес деректер жоқ',
+      noData: 'Деректер жоқ',
+      titles: ['List 1', 'List 2'],
+      filterPlaceholder: 'Кілт сөзді енгізіңіз',
+      noCheckedFormat: '{total} элэмэнт',
+      hasCheckedFormat: '{checked}/{total} құсбелгісі қойылды'
+    }
+  }
+};

+ 109 - 0
src/locale/lang/lt.js

@@ -0,0 +1,109 @@
+export default {
+  el: {
+    colorpicker: {
+      confirm: 'OK',
+      clear: 'Valyti'
+    },
+    datepicker: {
+      now: 'Dabar',
+      today: 'Šiandien',
+      cancel: 'Atšaukti',
+      clear: 'Vakyti',
+      confirm: 'OK',
+      selectDate: 'Pasirink datą',
+      selectTime: 'Pasirink laiką',
+      startDate: 'Data nuo',
+      startTime: 'Laikas nuo',
+      endDate: 'Data iki',
+      endTime: 'Laikas iki',
+      prevYear: 'Metai atgal',
+      nextYear: 'Metai į priekį',
+      prevMonth: 'Mėn. atgal',
+      nextMonth: 'Mėn. į priekį',
+      year: '',
+      month1: 'Sausis',
+      month2: 'Vasaris',
+      month3: 'Kovas',
+      month4: 'Balandis',
+      month5: 'Gegužė',
+      month6: 'Birželis',
+      month7: 'Liepa',
+      month8: 'Rugpjūtis',
+      month9: 'Rugsėjis',
+      month10: 'Spalis',
+      month11: 'Lapkritis',
+      month12: 'Gruodis',
+      // week: 'savaitė',
+      weeks: {
+        sun: 'S.',
+        mon: 'Pr.',
+        tue: 'A.',
+        wed: 'T.',
+        thu: 'K.',
+        fri: 'Pn.',
+        sat: 'Š.'
+      },
+      months: {
+        jan: 'Sau',
+        feb: 'Vas',
+        mar: 'Kov',
+        apr: 'Bal',
+        may: 'Geg',
+        jun: 'Bir',
+        jul: 'Lie',
+        aug: 'Rugp',
+        sep: 'Rugs',
+        oct: 'Spa',
+        nov: 'Lap',
+        dec: 'Gruo'
+      }
+    },
+    select: {
+      loading: 'Kraunasi',
+      noMatch: 'Duomenų nerasta',
+      noData: 'Nėra duomenų',
+      placeholder: 'Pasirink'
+    },
+    cascader: {
+      noMatch: 'Duomenų nerasta',
+      loading: 'Kraunasi',
+      placeholder: 'Pasirink'
+    },
+    pagination: {
+      goto: 'Eiti į',
+      pagesize: '/p',
+      total: 'Viso {total}',
+      pageClassifier: ''
+    },
+    messagebox: {
+      title: 'Žinutė',
+      confirm: 'OK',
+      cancel: 'Atšaukti',
+      error: 'Klaida įvestuose duomenyse'
+    },
+    upload: {
+      deleteTip: 'spauskite "Trinti" norėdami pašalinti',
+      delete: 'Trinti',
+      preview: 'Peržiūrėti',
+      continue: 'Toliau'
+    },
+    table: {
+      emptyText: 'Duomenų nerasta',
+      confirmFilter: 'Patvirtinti',
+      resetFilter: 'Atstatyti',
+      clearFilter: 'Išvalyti',
+      sumText: 'Suma'
+    },
+    tree: {
+      emptyText: 'Nėra duomenų'
+    },
+    transfer: {
+      noMatch: 'Duomenų nerasta',
+      noData: 'Nėra duomenų',
+      titles: ['Sąrašas 1', 'Sąrašas 2'],
+      filterPlaceholder: 'Įvesk raktažodį',
+      noCheckedFormat: 'Viso: {total}',
+      hasCheckedFormat: 'Pažymėta {checked} iš {total}'
+    }
+  }
+};

+ 109 - 0
src/locale/lang/mn.js

@@ -0,0 +1,109 @@
+export default {
+  el: {
+    colorpicker: {
+      confirm: 'Тийм',
+      clear: 'Цэвэрлэх'
+    },
+    datepicker: {
+      now: 'Одоо',
+      today: 'Өнөөдөр',
+      cancel: 'Болих',
+      clear: 'Цэвэрлэх',
+      confirm: 'Тийм',
+      selectDate: 'Огноог сонго',
+      selectTime: 'Цагийг сонго',
+      startDate: 'Эхлэх огноо',
+      startTime: 'Эхлэх цаг',
+      endDate: 'Дуусах огноо',
+      endTime: 'Дуусах цаг',
+      prevYear: 'Өмнөх жил',
+      nextYear: 'Дараа жил',
+      prevMonth: 'Өмнөх сар',
+      nextMonth: 'Дараа сар',
+      year: 'он',
+      month1: '1 сар',
+      month2: '2 сар',
+      month3: '3 сар',
+      month4: '4 сар',
+      month5: '5 сар',
+      month6: '6 сар',
+      month7: '7 сар',
+      month8: '8 сар',
+      month9: '9 сар',
+      month10: '10 сар',
+      month11: '11 сар',
+      month12: '12 сар',
+      week: 'Долоо хоног',
+      weeks: {
+        sun: 'Ням',
+        mon: 'Дав',
+        tue: 'Мяг',
+        wed: 'Лха',
+        thu: 'Пүр',
+        fri: 'Баа',
+        sat: 'Бям'
+      },
+      months: {
+        jan: '1 сар',
+        feb: '2 сар',
+        mar: '3 сар',
+        apr: '4 сар',
+        may: '5 сар',
+        jun: '6 сар',
+        jul: '7 сар',
+        aug: '8 сар',
+        sep: '9 сар',
+        oct: '10 сар',
+        nov: '11 сар',
+        dec: '12 сар'
+      }
+    },
+    select: {
+      loading: 'Ачаалж байна',
+      noMatch: 'Тохирох өгөгдөл байхгүй',
+      noData: 'Өгөгдөл байхгүй',
+      placeholder: 'Сонгох'
+    },
+    cascader: {
+      noMatch: 'Тохирох өгөгдөл байхгүй',
+      loading: 'Ачаалж байна',
+      placeholder: 'Сонгох'
+    },
+    pagination: {
+      goto: 'Очих',
+      pagesize: '/хуудас',
+      total: 'Нийт {total}',
+      pageClassifier: ''
+    },
+    messagebox: {
+      title: 'Зурвас',
+      confirm: 'Тийм',
+      cancel: 'Болих',
+      error: 'Буруу утга'
+    },
+    upload: {
+      deleteTip: 'Устгахын дарж арилга',
+      delete: 'Устгах',
+      preview: 'Өмнөх',
+      continue: 'Үргэлжлүүлэх'
+    },
+    table: {
+      emptyText: 'Өгөгдөл байхгүй',
+      confirmFilter: 'Зөвшөөрөх',
+      resetFilter: 'Цэвэрлэх',
+      clearFilter: 'Бүгд',
+      sumText: 'Нийт'
+    },
+    tree: {
+      emptyText: 'Өгөгдөл байхгүй'
+    },
+    transfer: {
+      noMatch: 'Тохирох өгөгдөл байхгүй',
+      noData: 'Өгөгдөл байхгүй',
+      titles: ['Жагсаалт 1', 'Жагсаалт 2'],
+      filterPlaceholder: 'Утга оруул',
+      noCheckedFormat: '{total} өгөгдөл',
+      hasCheckedFormat: '{checked}/{total} сонгосон'
+    }
+  }
+};

+ 12 - 12
src/locale/lang/nl.js

@@ -2,7 +2,7 @@ export default {
   el: {
     colorpicker: {
       confirm: 'Bevestig',
-      clear: 'Legen'
+      clear: 'Wissen'
     },
     datepicker: {
       now: 'Nu',
@@ -16,10 +16,10 @@ export default {
       startTime: 'Starttijd',
       endDate: 'Einddatum',
       endTime: 'Eindtijd',
-      prevYear: 'Previous Year', // to be translated
-      nextYear: 'Next Year', // to be translated
-      prevMonth: 'Previous Month', // to be translated
-      nextMonth: 'Next Month', // to be translated
+      prevYear: 'Vorig jaar',
+      nextYear: 'Volgend jaar',
+      prevMonth: 'Vorige maand',
+      nextMonth: 'Volgende maand',
       year: '',
       month1: 'januari',
       month2: 'februari',
@@ -71,7 +71,7 @@ export default {
     },
     pagination: {
       goto: 'Ga naar',
-      pagesize: '/page',
+      pagesize: '/pagina',
       total: 'Totaal {total}',
       pageClassifier: ''
     },
@@ -82,7 +82,7 @@ export default {
       error: 'Ongeldige invoer'
     },
     upload: {
-      deleteTip: 'press delete to remove', // to be translated
+      deleteTip: 'Kies verwijder om te wissen',
       delete: 'Verwijder',
       preview: 'Voorbeeld',
       continue: 'Doorgaan'
@@ -92,7 +92,7 @@ export default {
       confirmFilter: 'Bevestigen',
       resetFilter: 'Reset',
       clearFilter: 'Alles',
-      sumText: 'Sum' // to be translated
+      sumText: 'Som'
     },
     tree: {
       emptyText: 'Geen data'
@@ -100,10 +100,10 @@ export default {
     transfer: {
       noMatch: 'Geen overeenkomende resultaten',
       noData: 'Geen data',
-      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: ['Lijst 1', 'Lijst 2'],
+      filterPlaceholder: 'Geef zoekwoerd',
+      noCheckedFormat: '{total} items',
+      hasCheckedFormat: '{checked}/{total} geselecteerd'
     }
   }
 };

+ 27 - 21
src/utils/clickoutside.js

@@ -12,6 +12,30 @@ let seed = 0;
 !Vue.prototype.$isServer && on(document, 'mouseup', e => {
   nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
 });
+
+function createDocumentHandler(el, binding, vnode) {
+  return function(mouseup = {}, mousedown = {}) {
+    if (!vnode ||
+      !vnode.context ||
+      !mouseup.target ||
+      !mousedown.target ||
+      el.contains(mouseup.target) ||
+      el.contains(mousedown.target) ||
+      el === mouseup.target ||
+      (vnode.context.popperElm &&
+      (vnode.context.popperElm.contains(mouseup.target) ||
+      vnode.context.popperElm.contains(mousedown.target)))) return;
+
+    if (binding.expression &&
+      el[ctx].methodName &&
+      vnode.context[el[ctx].methodName]) {
+      vnode.context[el[ctx].methodName]();
+    } else {
+      el[ctx].bindingFn && el[ctx].bindingFn();
+    }
+  };
+}
+
 /**
  * v-clickoutside
  * @desc 点击元素外面才会触发的事件
@@ -24,34 +48,16 @@ export default {
   bind(el, binding, vnode) {
     nodeList.push(el);
     const id = seed++;
-    const documentHandler = function(mouseup = {}, mousedown = {}) {
-      if (!vnode.context ||
-        !mouseup.target ||
-        !mousedown.target ||
-        el.contains(mouseup.target) ||
-        el.contains(mousedown.target) ||
-        el === mouseup.target ||
-        (vnode.context.popperElm &&
-        (vnode.context.popperElm.contains(mouseup.target) ||
-        vnode.context.popperElm.contains(mousedown.target)))) return;
-
-      if (binding.expression &&
-        el[ctx].methodName &&
-        vnode.context[el[ctx].methodName]) {
-        vnode.context[el[ctx].methodName]();
-      } else {
-        el[ctx].bindingFn && el[ctx].bindingFn();
-      }
-    };
     el[ctx] = {
       id,
-      documentHandler,
+      documentHandler: createDocumentHandler(el, binding, vnode),
       methodName: binding.expression,
       bindingFn: binding.value
     };
   },
 
-  update(el, binding) {
+  update(el, binding, vnode) {
+    el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
     el[ctx].methodName = binding.expression;
     el[ctx].bindingFn = binding.value;
   },

+ 2 - 1
src/utils/popper.js

@@ -909,6 +909,7 @@
 
         var len         = isVertical ? 'height' : 'width';
         var side        = isVertical ? 'top' : 'left';
+        var translate   = isVertical ? 'translateY' : 'translateX';
         var altSide     = isVertical ? 'left' : 'top';
         var opSide      = isVertical ? 'bottom' : 'right';
         var arrowSize   = getOuterSizes(arrow)[len];
@@ -932,7 +933,7 @@
         var sideValue = center - popper[side];
 
         // prevent arrow from being placed not contiguously to its popper
-        sideValue = Math.max(Math.min(popper[len] - arrowSize - 3, sideValue), 3);
+        sideValue = Math.max(Math.min(popper[len] - arrowSize - 8, sideValue), 8);
         arrowStyle[side] = sideValue;
         arrowStyle[altSide] = ''; // make sure to remove any old style from the arrow
 

+ 2 - 3
test/unit/specs/dropdown.spec.js

@@ -102,12 +102,11 @@ describe('Dropdown', () => {
     triggerEvent(triggerElm, 'mouseenter');
     dropdown.$nextTick(_ => {
       expect(dropdown.visible).to.not.true;
-
       triggerElm.click();
-      dropdown.$nextTick(_ => {
+      setTimeout(_ => {
         expect(dropdown.visible).to.be.true;
         done();
-      });
+      }, 300);
     });
   });
   it('split button', done => {

+ 18 - 3
test/unit/specs/message-box.spec.js

@@ -99,15 +99,30 @@ describe('MessageBox', () => {
       inputErrorMessage: 'validation failed'
     });
     setTimeout(() => {
-      expect(document.querySelector('.el-message-box__input')).to.exist;
       const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
+      expect(messageBox.$el.querySelector('.el-message-box__input')).to.exist;
+      const haveFocus = messageBox.$el.querySelector('input').isSameNode(document.activeElement);
+      expect(haveFocus).to.true;
       messageBox.inputValue = 'no';
       setTimeout(() => {
-        expect(document.querySelector('.el-message-box__errormsg')
+        expect(messageBox.$el.querySelector('.el-message-box__errormsg')
           .textContent).to.equal('validation failed');
         done();
       }, 100);
-    }, 200);
+    }, 700);
+  });
+
+  it('prompt: focus on textarea', done => {
+    MessageBox.prompt('这是一段内容', {
+      inputType: 'textarea',
+      title: '标题名称'
+    });
+    setTimeout(() => {
+      const messageBox = document.querySelector('.el-message-box__wrapper').__vue__.$parent;
+      const haveFocus = messageBox.$el.querySelector('textarea').isSameNode(document.activeElement);
+      expect(haveFocus).to.true;
+      done();
+    }, 700);
   });
 
   describe('custom validator', () => {

+ 15 - 11
test/unit/specs/pagination.spec.js

@@ -223,20 +223,24 @@ describe('Pagination', () => {
     };
 
     changeValue(1);
-
     setTimeout(() => {
-      expect(vm.page).to.equal(1);
-
-      changeValue(10000);
-
+      expect(input.value).to.equal(1);
+      // 多次输入不在min-max区间内的数字
+      changeValue(0);
       setTimeout(() => {
-        expect(vm.page).to.equal(10);
-
-        changeValue('我好帅');
-
+        expect(input.value).to.equal(1);
+        changeValue(0);
         setTimeout(() => {
-          expect(vm.page).to.equal(1);
-          done();
+          expect(input.value).to.equal(1);
+          changeValue(1000);
+          setTimeout(() => {
+            expect(input.value).to.equal(10);
+            changeValue(1000);
+            setTimeout(() => {
+              expect(input.value).to.equal(10);
+              done();
+            }, 50);
+          }, 50);
         }, 50);
       }, 50);
     }, 50);

+ 24 - 0
test/unit/specs/time-picker.spec.js

@@ -26,6 +26,30 @@ describe('TimePicker', () => {
     expect(vm.$el.querySelector('input').value).to.equal('18-40-00');
   });
 
+  it('set AM/PM format', done => {
+    vm = createTest(TimePicker, {
+      format: 'hh:mm:ss A',
+      value: new Date(2016, 9, 10, 18, 40)
+    }, true);
+
+    const input = vm.$el.querySelector('input');
+
+    expect(vm.$el.querySelector('input').value).to.equal('06:40:00 PM');
+
+    input.blur();
+    input.focus();
+
+    setTimeout(_ => {
+      const list = vm.picker.$el.querySelectorAll('.el-time-spinner__list');
+      const hoursEl = list[0];
+      expect(hoursEl.querySelectorAll('.el-time-spinner__item')[0].textContent).to.equal('12 AM');
+      expect(hoursEl.querySelectorAll('.el-time-spinner__item')[1].textContent).to.equal('01 AM');
+      expect(hoursEl.querySelectorAll('.el-time-spinner__item')[12].textContent).to.equal('12 PM');
+      expect(hoursEl.querySelectorAll('.el-time-spinner__item')[15].textContent).to.equal('03 PM');
+      done();
+    }, DELAY);
+  });
+
   it('default value', done => {
     vm = createTest(TimePicker, {
       value: new Date(2016, 9, 10, 18, 40)

+ 286 - 0
types/element-ui.d.ts

@@ -0,0 +1,286 @@
+import Vue from 'vue'
+import { ElementUIComponent, ElementUIComponentSize, ElementUIHorizontalAlignment } from './component'
+
+import { ElAlert } from './alert'
+import { ElAside } from './aside'
+import { ElAutocomplete } from './autocomplete'
+import { ElBadge } from './badge'
+import { ElBreadcrumb } from './breadcrumb'
+import { ElBreadcrumbItem } from './breadcrumb-item'
+import { ElButton } from './button'
+import { ElButtonGroup } from './button-group'
+import { ElCard } from './card'
+import { ElCarousel } from './carousel'
+import { ElCarouselItem } from './carousel-item'
+import { ElCascader } from './cascader'
+import { ElCheckbox } from './checkbox'
+import { ElCheckboxGroup } from './checkbox-group'
+import { ElCol } from './col'
+import { ElCollapse } from './collapse'
+import { ElCollapseItem } from './collapse-item'
+import { ElColorPicker } from './color-picker'
+import { ElContainer } from './container'
+import { ElDatePicker } from './date-picker'
+import { ElDialog } from './dialog'
+import { ElDropdown } from './dropdown'
+import { ElDropdownItem } from './dropdown-item'
+import { ElDropdownMenu } from './dropdown-menu'
+import { ElFooter } from './footer'
+import { ElForm } from './form'
+import { ElFormItem } from './form-item'
+import { ElHeader } from './header'
+import { ElInput } from './input'
+import { ElInputNumber } from './input-number'
+import { ElLoading } from './loading'
+import { ElMain } from './main'
+import { ElMenu } from './menu'
+import { ElMenuItem } from './menu-item'
+import { ElMenuItemGroup } from './menu-item-group'
+import { ElMessage } from './message'
+import { ElMessageBox } from './message-box'
+import { ElNotification } from './notification'
+import { ElOption } from './option'
+import { ElOptionGroup } from './option-group'
+import { ElPagination } from './pagination'
+import { ElPopover } from './popover'
+import { ElProgress } from './progress'
+import { ElRate } from './rate'
+import { ElRadio } from './radio'
+import { ElRadioButton } from './radio-button'
+import { ElRadioGroup } from './radio-group'
+import { ElRow } from './row'
+import { ElSelect } from './select'
+import { ElSlider } from './slider'
+import { ElStep } from './step'
+import { ElSteps } from './steps'
+import { ElSubmenu } from './submenu'
+import { ElSwitch } from './switch'
+import { ElTable } from './table'
+import { ElTableColumn } from './table-column'
+import { ElTag } from './tag'
+import { ElTabs } from './tabs'
+import { ElTabPane } from './tab-pane'
+import { ElTimePicker } from './time-picker'
+import { ElTooltip } from './tooltip'
+import { ElTransfer } from './transfer'
+import { ElTree } from './tree'
+import { ElUpload } from './upload'
+
+export interface InstallationOptions {
+  locale: any,
+  i18n: any,
+  size: string
+}
+
+/** The version of element-ui */
+export const version: string
+
+/**
+ * Install all element-ui components into Vue.
+ * Please do not invoke this method directly.
+ * Call `Vue.use(ElementUI)` to install.
+ */
+export function install (vue: typeof Vue, options: InstallationOptions): void
+
+/** ElementUI component common definition */
+export type Component = ElementUIComponent
+
+/** Component size definition for button, input, etc */
+export type ComponentSize = ElementUIComponentSize
+
+/** Horizontal alignment */
+export type HorizontalAlignment = ElementUIHorizontalAlignment
+
+/** Show animation while loading data */
+export const Loading: ElLoading
+
+/** Used to show feedback after an activity. The difference with Notification is that the latter is often used to show a system level passive notification. */
+export const Message: ElMessage
+
+/** A set of modal boxes simulating system message box, mainly for message prompt, success tips, error messages and query information */
+export const MessageBox: ElMessageBox
+
+/** Displays a global notification message at the upper right corner of the page */
+export const Notification: ElNotification
+
+// TS cannot merge imported class with namespace, so declare subclasses instead
+
+/** Alert Component */
+export class Alert extends ElAlert {}
+
+/** Aside Component */
+export class Aside extends ElAside {}
+
+/** Autocomplete Component */
+export class Autocomplete extends ElAutocomplete {}
+
+/** Bagde Component */
+export class Badge extends ElBadge {}
+
+/** Breadcrumb Component */
+export class Breadcrumb extends ElBreadcrumb {}
+
+/** Breadcrumb Item Component */
+export class BreadcrumbItem extends ElBreadcrumbItem {}
+
+/** Button Component */
+export class Button extends ElButton {}
+
+/** Button Group Component */
+export class ButtonGroup extends ElButtonGroup {}
+
+/** Card Component */
+export class Card extends ElCard {}
+
+/** Cascader Component */
+export class Cascader extends ElCascader {}
+
+/** Carousel Component */
+export class Carousel extends ElCarousel {}
+
+/** Carousel Item Component */
+export class CarouselItem extends ElCarouselItem {}
+
+/** Checkbox Component */
+export class Checkbox extends ElCheckbox {}
+
+/** Checkbox Group Component */
+export class CheckboxGroup extends ElCheckboxGroup {}
+
+/** Colunm Layout Component */
+export class Col extends ElCol {}
+
+/** Collapse Component */
+export class Collapse extends ElCollapse {}
+
+/** Collapse Item Component */
+export class CollapseItem extends ElCollapseItem {}
+
+/** Color Picker Component */
+export class ColorPicker extends ElColorPicker {}
+
+/** Container Component */
+export class Container extends ElContainer {}
+
+/** Date Picker Component */
+export class DatePicker extends ElDatePicker {}
+
+/** Dialog Component */
+export class Dialog extends ElDialog {}
+
+/** Dropdown Component */
+export class Dropdown extends ElDropdown {}
+
+/** Dropdown Item Component */
+export class DropdownItem extends ElDropdownItem {}
+
+/** Dropdown Menu Component */
+export class DropdownMenu extends ElDropdownMenu {}
+
+/** Footer Component */
+export class Footer extends ElFooter {}
+
+/** Form Component */
+export class Form extends ElForm {}
+
+/** Form Item Component */
+export class FormItem extends ElFormItem {}
+
+/** Header Component */
+export class Header extends ElHeader {}
+
+/** Input Component */
+export class Input extends ElInput {}
+
+/** Input Number Component */
+export class InputNumber extends ElInputNumber {}
+
+/** Main Component */
+export class Main extends ElMain {}
+
+/** Menu that provides navigation for your website */
+export class Menu extends ElMenu {}
+
+/** Menu Item Component */
+export class MenuItem extends ElMenuItem {}
+
+/** Menu Item Group Component */
+export class MenuItemGroup extends ElMenuItemGroup {}
+
+/** Dropdown Select Option Component */
+export class Option extends ElOption {}
+
+/** Dropdown Select Option Group Component */
+export class OptionGroup extends ElOptionGroup {}
+
+/** Pagination Component */
+export class Pagination extends ElPagination {}
+
+/** Popover Component */
+export class Popover extends ElPopover {}
+
+/** Progress Component */
+export class Progress extends ElProgress {}
+
+/** Rate Component */
+export class Rate extends ElRate {}
+
+/** Radio Component */
+export class Radio extends ElRadio {}
+
+/** Radio Button Component */
+export class RadioButton extends ElRadioButton {}
+
+/** Radio Group Component */
+export class RadioGroup extends ElRadioGroup {}
+
+/** Row Layout Component */
+export class Row extends ElRow {}
+
+/** Dropdown Select Component */
+export class Select extends ElSelect {}
+
+/** Slider Component */
+export class Slider extends ElSlider {}
+
+/** Step Component */
+export class Step extends ElStep {}
+
+/** Steps Component */
+export class Steps extends ElSteps {}
+
+/** Submenu Component */
+export class Submenu extends ElSubmenu {}
+
+/** Switch Component */
+export class Switch extends ElSwitch {}
+
+/** Table Component */
+export class Table extends ElTable {}
+
+/** Table Column Component */
+export class TableColumn extends ElTableColumn {}
+
+/** Tabs Component */
+export class Tabs extends ElTabs {}
+
+/** Tab Pane Component */
+export class TabPane extends ElTabPane {}
+
+/** Tag Component */
+export class Tag extends ElTag {}
+
+/** Time Picker and Time Select Component */
+export class TimePicker extends ElTimePicker {}
+
+/** Tooltip Component */
+export class Tooltip extends ElTooltip {}
+
+/** Transfer Component */
+export class Transfer extends ElTransfer {}
+
+/** Tree Component */
+export class Tree extends ElTree {}
+
+/** Upload Component */
+export class Upload extends ElUpload {}

+ 2 - 284
types/index.d.ts

@@ -1,286 +1,4 @@
-import Vue from 'vue'
-import { ElementUIComponent, ElementUIComponentSize, ElementUIHorizontalAlignment } from './component'
-
-import { ElAlert } from './alert'
-import { ElAside } from './aside'
-import { ElAutocomplete } from './autocomplete'
-import { ElBadge } from './badge'
-import { ElBreadcrumb } from './breadcrumb'
-import { ElBreadcrumbItem } from './breadcrumb-item'
-import { ElButton } from './button'
-import { ElButtonGroup } from './button-group'
-import { ElCard } from './card'
-import { ElCarousel } from './carousel'
-import { ElCarouselItem } from './carousel-item'
-import { ElCascader } from './cascader'
-import { ElCheckbox } from './checkbox'
-import { ElCheckboxGroup } from './checkbox-group'
-import { ElCol } from './col'
-import { ElCollapse } from './collapse'
-import { ElCollapseItem } from './collapse-item'
-import { ElColorPicker } from './color-picker'
-import { ElContainer } from './container'
-import { ElDatePicker } from './date-picker'
-import { ElDialog } from './dialog'
-import { ElDropdown } from './dropdown'
-import { ElDropdownItem } from './dropdown-item'
-import { ElDropdownMenu } from './dropdown-menu'
-import { ElFooter } from './footer'
-import { ElForm } from './form'
-import { ElFormItem } from './form-item'
-import { ElHeader } from './header'
-import { ElInput } from './input'
-import { ElInputNumber } from './input-number'
-import { ElLoading } from './loading'
-import { ElMain } from './main'
-import { ElMenu } from './menu'
-import { ElMenuItem } from './menu-item'
-import { ElMenuItemGroup } from './menu-item-group'
-import { ElMessage } from './message'
-import { ElMessageBox } from './message-box'
-import { ElNotification } from './notification'
-import { ElOption } from './option'
-import { ElOptionGroup } from './option-group'
-import { ElPagination } from './pagination'
-import { ElPopover } from './popover'
-import { ElProgress } from './progress'
-import { ElRate } from './rate'
-import { ElRadio } from './radio'
-import { ElRadioButton } from './radio-button'
-import { ElRadioGroup } from './radio-group'
-import { ElRow } from './row'
-import { ElSelect } from './select'
-import { ElSlider } from './slider'
-import { ElStep } from './step'
-import { ElSteps } from './steps'
-import { ElSubmenu } from './submenu'
-import { ElSwitch } from './switch'
-import { ElTable } from './table'
-import { ElTableColumn } from './table-column'
-import { ElTag } from './tag'
-import { ElTabs } from './tabs'
-import { ElTabPane } from './tab-pane'
-import { ElTimePicker } from './time-picker'
-import { ElTooltip } from './tooltip'
-import { ElTransfer } from './transfer'
-import { ElTree } from './tree'
-import { ElUpload } from './upload'
-
-declare namespace ElementUI {
-  export interface InstallationOptions {
-    locale: any,
-    i18n: any
-  }
-
-  /**
-   * Install all element-ui components into Vue.
-   * Please do not invoke this method directly.
-   * Call `Vue.use(ElementUI)` to install.
-   */
-  export function install (vue: typeof Vue, options: ElementUI.InstallationOptions): void
-
-  /** ElementUI component common definition */
-  export type Component = ElementUIComponent
-
-  /** Component size definition for button, input, etc */
-  export type ComponentSize = ElementUIComponentSize
-
-  /** Horizontal alignment */
-  export type HorizontalAlignment = ElementUIHorizontalAlignment
-
-  /** Show animation while loading data */
-  export const Loading: ElLoading
-
-  /** Used to show feedback after an activity. The difference with Notification is that the latter is often used to show a system level passive notification. */
-  export const Message: ElMessage
-
-  /** A set of modal boxes simulating system message box, mainly for message prompt, success tips, error messages and query information */
-  export const MessageBox: ElMessageBox
-
-  /** Displays a global notification message at the upper right corner of the page */
-  export const Notification: ElNotification
-
-  // TS cannot merge imported class with namespace, so declare subclasses instead
-
-  /** Alert Component */
-  export class Alert extends ElAlert {}
-
-  /** Aside Component */
-  export class Aside extends ElAside {}
-
-  /** Autocomplete Component */
-  export class Autocomplete extends ElAutocomplete {}
-
-  /** Bagde Component */
-  export class Badge extends ElBadge {}
-
-  /** Breadcrumb Component */
-  export class Breadcrumb extends ElBreadcrumb {}
-
-  /** Breadcrumb Item Component */
-  export class BreadcrumbItem extends ElBreadcrumbItem {}
-
-  /** Button Component */
-  export class Button extends ElButton {}
-
-  /** Button Group Component */
-  export class ButtonGroup extends ElButtonGroup {}
-
-  /** Card Component */
-  export class Card extends ElCard {}
-
-  /** Cascader Component */
-  export class Cascader extends ElCascader {}
-
-  /** Carousel Component */
-  export class Carousel extends ElCarousel {}
-
-  /** Carousel Item Component */
-  export class CarouselItem extends ElCarouselItem {}
-
-  /** Checkbox Component */
-  export class Checkbox extends ElCheckbox {}
-
-  /** Checkbox Group Component */
-  export class CheckboxGroup extends ElCheckboxGroup {}
-
-  /** Colunm Layout Component */
-  export class Col extends ElCol {}
-
-  /** Collapse Component */
-  export class Collapse extends ElCollapse {}
-
-  /** Collapse Item Component */
-  export class CollapseItem extends ElCollapseItem {}
-
-  /** Color Picker Component */
-  export class ColorPicker extends ElColorPicker {}
-
-  /** Container Component */
-  export class Container extends ElContainer {}
-
-  /** Date Picker Component */
-  export class DatePicker extends ElDatePicker {}
-
-  /** Dialog Component */
-  export class Dialog extends ElDialog {}
-
-  /** Dropdown Component */
-  export class Dropdown extends ElDropdown {}
-
-  /** Dropdown Item Component */
-  export class DropdownItem extends ElDropdownItem {}
-
-  /** Dropdown Menu Component */
-  export class DropdownMenu extends ElDropdownMenu {}
-
-  /** Footer Component */
-  export class Footer extends ElFooter {}
-
-  /** Form Component */
-  export class Form extends ElForm {}
-
-  /** Form Item Component */
-  export class FormItem extends ElFormItem {}
-
-  /** Header Component */
-  export class Header extends ElHeader {}
-
-  /** Input Component */
-  export class Input extends ElInput {}
-
-  /** Input Number Component */
-  export class InputNumber extends ElInputNumber {}
-
-  /** Main Component */
-  export class Main extends ElMain {}
-
-  /** Menu that provides navigation for your website */
-  export class Menu extends ElMenu {}
-
-  /** Menu Item Component */
-  export class MenuItem extends ElMenuItem {}
-
-  /** Menu Item Group Component */
-  export class MenuItemGroup extends ElMenuItemGroup {}
-
-  /** Dropdown Select Option Component */
-  export class Option extends ElOption {}
-
-  /** Dropdown Select Option Group Component */
-  export class OptionGroup extends ElOptionGroup {}
-
-  /** Pagination Component */
-  export class Pagination extends ElPagination {}
-
-  /** Popover Component */
-  export class Popover extends ElPopover {}
-
-  /** Progress Component */
-  export class Progress extends ElProgress {}
-
-  /** Rate Component */
-  export class Rate extends ElRate {}
-
-  /** Radio Component */
-  export class Radio extends ElRadio {}
-
-  /** Radio Button Component */
-  export class RadioButton extends ElRadioButton {}
-
-  /** Radio Group Component */
-  export class RadioGroup extends ElRadioGroup {}
-
-  /** Row Layout Component */
-  export class Row extends ElRow {}
-
-  /** Dropdown Select Component */
-  export class Select extends ElSelect {}
-
-  /** Slider Component */
-  export class Slider extends ElSlider {}
-
-  /** Step Component */
-  export class Step extends ElStep {}
-
-  /** Steps Component */
-  export class Steps extends ElSteps {}
-
-  /** Submenu Component */
-  export class Submenu extends ElSubmenu {}
-
-  /** Switch Component */
-  export class Switch extends ElSwitch {}
-
-  /** Table Component */
-  export class Table extends ElTable {}
-
-  /** Table Column Component */
-  export class TableColumn extends ElTableColumn {}
-
-  /** Tabs Component */
-  export class Tabs extends ElTabs {}
-
-  /** Tab Pane Component */
-  export class TabPane extends ElTabPane {}
-
-  /** Tag Component */
-  export class Tag extends ElTag {}
-
-  /** Time Picker and Time Select Component */
-  export class TimePicker extends ElTimePicker {}
-
-  /** Tooltip Component */
-  export class Tooltip extends ElTooltip {}
-
-  /** Transfer Component */
-  export class Transfer extends ElTransfer {}
-
-  /** Tree Component */
-  export class Tree extends ElTree {}
-
-  /** Upload Component */
-  export class Upload extends ElUpload {}
-}
+export * from './element-ui'
 
+import * as ElementUI from './element-ui'
 export default ElementUI

+ 42 - 10
yarn.lock

@@ -1302,6 +1302,13 @@ cli-width@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
 
+cli@~1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/cli/-/cli-1.0.1.tgz#22817534f24bfa4950c34d532d48ecbc621b8c14"
+  dependencies:
+    exit "0.1.2"
+    glob "^7.1.1"
+
 cliui@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
@@ -1366,13 +1373,7 @@ collections@^0.2.0:
   dependencies:
     weak-map "1.0.0"
 
-color-convert@^1.3.0:
-  version "1.8.2"
-  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.8.2.tgz#be868184d7c8631766d54e7078e2672d7c7e3339"
-  dependencies:
-    color-name "^1.1.1"
-
-color-convert@^1.9.0:
+color-convert@^1.3.0, color-convert@^1.9.0:
   version "1.9.0"
   resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a"
   dependencies:
@@ -1505,7 +1506,7 @@ connect@^3.3.5:
     parseurl "~1.3.1"
     utils-merge "1.0.0"
 
-console-browserify@^1.1.0:
+console-browserify@1.1.x, console-browserify@^1.1.0:
   version "1.1.0"
   resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10"
   dependencies:
@@ -2395,6 +2396,12 @@ eslint-plugin-html@*, eslint-plugin-html@^1.5.2:
   dependencies:
     htmlparser2 "^3.8.2"
 
+eslint-plugin-json@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-1.2.0.tgz#9ba73bb0be99d50093e889f5b968463d2a30efae"
+  dependencies:
+    jshint "^2.8.0"
+
 eslint-plugin-react@*, eslint-plugin-react@^6.2.0:
   version "6.8.0"
   resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.8.0.tgz#741ab5438a094532e5ce1bbb935d6832356f492d"
@@ -2548,6 +2555,10 @@ exit-hook@^1.0.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
 
+exit@0.1.2, exit@0.1.x:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+
 expand-braces@^0.1.1:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/expand-braces/-/expand-braces-0.1.2.tgz#488b1d1d2451cb3d3a6b192cfc030f44c5855fea"
@@ -3572,7 +3583,7 @@ html-webpack-plugin@^2.30.1:
     pretty-error "^2.0.2"
     toposort "^1.0.0"
 
-htmlparser2@^3.8.2, htmlparser2@~3.8.1:
+htmlparser2@3.8.x, htmlparser2@^3.8.2, htmlparser2@~3.8.1:
   version "3.8.3"
   resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
   dependencies:
@@ -4149,6 +4160,19 @@ jsesc@~0.5.0:
   version "0.5.0"
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
 
+jshint@^2.8.0:
+  version "2.9.5"
+  resolved "https://registry.yarnpkg.com/jshint/-/jshint-2.9.5.tgz#1e7252915ce681b40827ee14248c46d34e9aa62c"
+  dependencies:
+    cli "~1.0.0"
+    console-browserify "1.1.x"
+    exit "0.1.x"
+    htmlparser2 "3.8.x"
+    lodash "3.7.x"
+    minimatch "~3.0.2"
+    shelljs "0.3.x"
+    strip-json-comments "1.0.x"
+
 json-loader@^0.5.4, json-loader@^0.5.7:
   version "0.5.7"
   resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d"
@@ -4724,6 +4748,10 @@ lodash.values@~2.4.1:
   dependencies:
     lodash.keys "~2.4.1"
 
+lodash@3.7.x:
+  version "3.7.0"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.7.0.tgz#3678bd8ab995057c07ade836ed2ef087da811d45"
+
 lodash@^3.8.0:
   version "3.10.1"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
@@ -7014,6 +7042,10 @@ shebang-regex@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
 
+shelljs@0.3.x:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.3.0.tgz#3596e6307a781544f591f37da618360f31db57b1"
+
 shelljs@^0.7.0, shelljs@^0.7.4, shelljs@^0.7.5:
   version "0.7.5"
   resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.5.tgz#2eef7a50a21e1ccf37da00df767ec69e30ad0675"
@@ -7358,7 +7390,7 @@ strip-indent@^1.0.1:
   dependencies:
     get-stdin "^4.0.1"
 
-strip-json-comments@~1.0.1, strip-json-comments@~1.0.4:
+strip-json-comments@1.0.x, strip-json-comments@~1.0.1, strip-json-comments@~1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91"